~drizzle-trunk/drizzle/development

1240.7.1 by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes
1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
 *
1999.6.1 by kalebral at gmail
update Copyright strings to a more common format to help with creating the master debian copyright file
4
 *  Copyright (C) 2008-2009 Sun Microsystems, Inc.
1240.7.1 by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes
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; version 2 of the License.
9
 *
10
 *  This program is distributed in the hope that it will be useful,
11
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 *  GNU General Public License for more details.
14
 *
15
 *  You should have received a copy of the GNU General Public License
16
 *  along with this program; if not, write to the Free Software
17
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18
 */
19
2173.2.1 by Monty Taylor
Fixes incorrect usage of include
20
#include <config.h>
2154.2.24 by Brian Aker
Merge in all changes for current_session, etc.
21
2173.2.1 by Monty Taylor
Fixes incorrect usage of include
22
#include <drizzled/session.h>
23
#include <drizzled/item/uint.h>
24
#include <drizzled/item/float.h>
25
#include <drizzled/item/string.h>
26
#include <drizzled/optimizer/explain_plan.h>
27
#include <drizzled/optimizer/position.h>
28
#include <drizzled/optimizer/quick_ror_intersect_select.h>
29
#include <drizzled/optimizer/range.h>
30
#include <drizzled/sql_select.h>
31
#include <drizzled/join.h>
32
#include <drizzled/internal/m_string.h>
2154.2.24 by Brian Aker
Merge in all changes for current_session, etc.
33
#include <drizzled/select_result.h>
2234.1.3 by Olaf van der Spek
Refactor includes
34
#include <drizzled/sql_lex.h>
1240.7.1 by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes
35
1502.3.1 by iwamatsu at nigauri
Add cstdio include to files needing it. Fixes the build on some debian
36
#include <cstdio>
1240.7.1 by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes
37
#include <string>
1241.9.17 by Monty Taylor
Removed more bits from server_includes.
38
#include <sstream>
1858.1.1 by Padraig O'Sullivan
Replaced a uint8_t member with a standard bitset since it was being used as a bitset....
39
#include <bitset>
1240.7.1 by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes
40
41
using namespace std;
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
42
43
namespace drizzled
44
{
1240.7.1 by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes
45
46
static const string access_method_str[]=
47
{
48
  "UNKNOWN",
49
  "system",
50
  "const",
51
  "eq_ref",
52
  "ref",
53
  "MAYBE_REF",
54
  "ALL",
55
  "range",
56
  "index",
57
  "ref_or_null",
58
  "unique_subquery",
59
  "index_subquery",
60
  "index_merge"
61
};
62
1237.13.30 by Padraig O'Sullivan
Corrected a valgrind warning due to using std::string in the Select_Lex class whose memory is
63
static const string select_type_str[]=
64
{
65
  "PRIMARY",
66
  "SIMPLE",
67
  "DERIVED",
68
  "DEPENDENT SUBQUERY",
69
  "UNCACHEABLE SUBQUERY",
70
  "SUBQUERY",
71
  "DEPENDENT UNION",
72
  "UNCACHEABLE_UNION",
73
  "UNION",
74
  "UNION RESULT"
75
};
76
1240.7.1 by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes
77
void optimizer::ExplainPlan::printPlan()
78
{
79
  List<Item> item_list;
80
  Session *session= join->session;
81
  select_result *result= join->result;
82
  Item *item_null= new Item_null();
2254 by Brian Aker
Shift CHARSET_INFO to charset_info_st
83
  const charset_info_st * const cs= system_charset_info;
1240.7.1 by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes
84
  int quick_type;
85
  /* Don't log this into the slow query log */
86
  session->server_status&= ~(SERVER_QUERY_NO_INDEX_USED | SERVER_QUERY_NO_GOOD_INDEX_USED);
87
  join->unit->offset_limit_cnt= 0;
88
89
  /*
90
   NOTE: the number/types of items pushed into item_list must be in sync with
91
   EXPLAIN column types as they're "defined" in Session::send_explain_fields()
92
   */
93
  if (message)
94
  {
95
    item_list.push_back(new Item_int((int32_t)
96
                        join->select_lex->select_number));
1237.13.30 by Padraig O'Sullivan
Corrected a valgrind warning due to using std::string in the Select_Lex class whose memory is
97
    item_list.push_back(new Item_string(select_type_str[join->select_lex->type].c_str(),
98
                                        select_type_str[join->select_lex->type].length(),
1240.7.1 by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes
99
                                        cs));
100
    for (uint32_t i= 0; i < 7; i++)
101
      item_list.push_back(item_null);
102
2227.4.8 by Olaf van der Spek
Session::lex()
103
    if (join->session->lex().describe & DESCRIBE_EXTENDED)
1240.7.1 by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes
104
      item_list.push_back(item_null);
105
106
    item_list.push_back(new Item_string(message,strlen(message),cs));
107
    if (result->send_data(item_list))
108
      join->error= 1;
109
  }
110
  else if (join->select_lex == join->unit->fake_select_lex)
111
  {
112
    /*
113
       here we assume that the query will return at least two rows, so we
114
       show "filesort" in EXPLAIN. Of course, sometimes we'll be wrong
115
       and no filesort will be actually done, but executing all selects in
116
       the UNION to provide precise EXPLAIN information will hardly be
117
       appreciated :)
118
     */
119
    char table_name_buffer[NAME_LEN];
2179.2.1 by Olaf van der Spek
Rename List::empty to clear (std::list uses clear)
120
    item_list.clear();
1240.7.1 by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes
121
    /* id */
122
    item_list.push_back(new Item_null);
123
    /* select_type */
1237.13.30 by Padraig O'Sullivan
Corrected a valgrind warning due to using std::string in the Select_Lex class whose memory is
124
    item_list.push_back(new Item_string(select_type_str[join->select_lex->type].c_str(),
125
                                        select_type_str[join->select_lex->type].length(),
1240.7.1 by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes
126
                                        cs));
127
    /* table */
128
    {
129
      Select_Lex *sl= join->unit->first_select();
130
      uint32_t len= 6, lastop= 0;
131
      memcpy(table_name_buffer, STRING_WITH_LEN("<union"));
132
      for (; sl && len + lastop + 5 < NAME_LEN; sl= sl->next_select())
133
      {
134
        len+= lastop;
135
        lastop= snprintf(table_name_buffer + len, NAME_LEN - len,
136
            "%u,", sl->select_number);
137
      }
138
      if (sl || len + lastop >= NAME_LEN)
139
      {
140
        memcpy(table_name_buffer + len, STRING_WITH_LEN("...>") + 1);
141
        len+= 4;
142
      }
143
      else
144
      {
145
        len+= lastop;
146
        table_name_buffer[len - 1]= '>';  // change ',' to '>'
147
      }
148
      item_list.push_back(new Item_string(table_name_buffer, len, cs));
149
    }
150
    /* type */
151
    item_list.push_back(new Item_string(access_method_str[AM_ALL].c_str(),
152
                                        access_method_str[AM_ALL].length(),
153
                                        cs));
154
    /* possible_keys */
155
    item_list.push_back(item_null);
156
    /* key*/
157
    item_list.push_back(item_null);
158
    /* key_len */
159
    item_list.push_back(item_null);
160
    /* ref */
161
    item_list.push_back(item_null);
162
    /* in_rows */
2227.4.8 by Olaf van der Spek
Session::lex()
163
    if (join->session->lex().describe & DESCRIBE_EXTENDED)
1240.7.1 by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes
164
      item_list.push_back(item_null);
165
    /* rows */
166
    item_list.push_back(item_null);
167
    /* extra */
168
    if (join->unit->global_parameters->order_list.first)
169
      item_list.push_back(new Item_string("Using filesort",
170
                                          14, 
171
                                          cs));
172
    else
173
      item_list.push_back(new Item_string("", 0, cs));
174
175
    if (result->send_data(item_list))
176
      join->error= 1;
177
  }
178
  else
179
  {
180
    table_map used_tables= 0;
181
    for (uint32_t i= 0; i < join->tables; i++)
182
    {
183
      JoinTable *tab= join->join_tab + i;
184
      Table *table= tab->table;
185
      char keylen_str_buf[64];
2170.4.5 by Stewart Smith
convert explain_plan extra String to std::string. This means that add_info_string() also gets converted to std::string
186
      string extra;
1240.7.1 by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes
187
      char table_name_buffer[NAME_LEN];
2170.4.2 by Stewart Smith
replace char array and String with std::string in explain path
188
      string tmp1;
2170.4.3 by Stewart Smith
convert tmp2 in explain_plan to std::string instead of char[] buf and String, consequently also convert add_keys_and_length to deal with std::string for key_names parameter
189
      string tmp2;
2170.4.4 by Stewart Smith
tmp3 String to std::string in explain_plan (and used_lengths parameter to add_keys_and_lengths
190
      string tmp3;
1240.7.1 by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes
191
192
      quick_type= -1;
2179.2.1 by Olaf van der Spek
Rename List::empty to clear (std::list uses clear)
193
      item_list.clear();
1240.7.1 by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes
194
      /* id */
195
      item_list.push_back(new Item_uint((uint32_t)
196
            join->select_lex->select_number));
197
      /* select_type */
1237.13.30 by Padraig O'Sullivan
Corrected a valgrind warning due to using std::string in the Select_Lex class whose memory is
198
      item_list.push_back(new Item_string(select_type_str[join->select_lex->type].c_str(),
199
                                          select_type_str[join->select_lex->type].length(),
1240.7.1 by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes
200
                                          cs));
201
      if (tab->type == AM_ALL && tab->select && tab->select->quick)
202
      {
203
        quick_type= tab->select->quick->get_type();
1240.7.6 by Padraig O'Sullivan
Resolved one last conflict after the merge from trunk.
204
        if ((quick_type == optimizer::QuickSelectInterface::QS_TYPE_INDEX_MERGE) ||
205
            (quick_type == optimizer::QuickSelectInterface::QS_TYPE_ROR_INTERSECT) ||
206
            (quick_type == optimizer::QuickSelectInterface::QS_TYPE_ROR_UNION))
1240.7.1 by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes
207
          tab->type = AM_INDEX_MERGE;
208
        else
209
          tab->type = AM_RANGE;
210
      }
211
      /* table */
212
      if (table->derived_select_number)
213
      {
214
        /* Derived table name generation */
215
        int len= snprintf(table_name_buffer, 
216
                          sizeof(table_name_buffer)-1,
217
                          "<derived%u>",
218
                          table->derived_select_number);
219
        item_list.push_back(new Item_string(table_name_buffer, len, cs));
220
      }
221
      else
222
      {
223
        TableList *real_table= table->pos_in_table_list;
224
        item_list.push_back(new Item_string(real_table->alias,
1240.7.3 by Padraig O'Sullivan
Used std::string for the type in Select_Lex instead of char *.
225
                                            strlen(real_table->alias),
226
                                            cs));
1240.7.1 by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes
227
      }
228
      /* "type" column */
229
      item_list.push_back(new Item_string(access_method_str[tab->type].c_str(),
230
                                          access_method_str[tab->type].length(),
231
                                          cs));
232
      /* Build "possible_keys" value and add it to item_list */
233
      if (tab->keys.any())
234
      {
1578.2.10 by Brian Aker
keys and fields partial encapsulation.
235
        for (uint32_t j= 0; j < table->getShare()->sizeKeys(); j++)
1240.7.1 by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes
236
        {
237
          if (tab->keys.test(j))
238
          {
239
            if (tmp1.length())
2170.4.2 by Stewart Smith
replace char array and String with std::string in explain path
240
              tmp1.append(",");
1240.7.1 by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes
241
            tmp1.append(table->key_info[j].name,
2170.4.2 by Stewart Smith
replace char array and String with std::string in explain path
242
                        strlen(table->key_info[j].name));
1240.7.1 by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes
243
          }
244
        }
245
      }
246
      if (tmp1.length())
2170.4.2 by Stewart Smith
replace char array and String with std::string in explain path
247
        item_list.push_back(new Item_string(tmp1.c_str(),tmp1.length(),cs));
1240.7.1 by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes
248
      else
249
        item_list.push_back(item_null);
250
251
      /* Build "key", "key_len", and "ref" values and add them to item_list */
252
      if (tab->ref.key_parts)
253
      {
1535 by Brian Aker
Rename of KEY to KeyInfo
254
        KeyInfo *key_info= table->key_info+ tab->ref.key;
1240.7.1 by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes
255
        item_list.push_back(new Item_string(key_info->name,
256
                                            strlen(key_info->name),
257
                                            system_charset_info));
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
258
        uint32_t length= internal::int64_t2str(tab->ref.key_length, keylen_str_buf, 10) -
1240.7.3 by Padraig O'Sullivan
Used std::string for the type in Select_Lex instead of char *.
259
                                     keylen_str_buf;
1240.7.1 by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes
260
        item_list.push_back(new Item_string(keylen_str_buf, 
261
                                            length,
262
                                            system_charset_info));
263
        for (StoredKey **ref= tab->ref.key_copy; *ref; ref++)
264
        {
265
          if (tmp2.length())
2170.4.3 by Stewart Smith
convert tmp2 in explain_plan to std::string instead of char[] buf and String, consequently also convert add_keys_and_length to deal with std::string for key_names parameter
266
            tmp2.append(",");
267
          tmp2.append((*ref)->name(),
268
                      strlen((*ref)->name()));
1240.7.1 by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes
269
        }
2170.4.3 by Stewart Smith
convert tmp2 in explain_plan to std::string instead of char[] buf and String, consequently also convert add_keys_and_length to deal with std::string for key_names parameter
270
        item_list.push_back(new Item_string(tmp2.c_str(),tmp2.length(),cs));
1240.7.1 by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes
271
      }
272
      else if (tab->type == AM_NEXT)
273
      {
1535 by Brian Aker
Rename of KEY to KeyInfo
274
        KeyInfo *key_info=table->key_info+ tab->index;
1240.7.1 by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes
275
        item_list.push_back(new Item_string(key_info->name,
276
              strlen(key_info->name),cs));
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
277
        uint32_t length= internal::int64_t2str(key_info->key_length, keylen_str_buf, 10) -
1240.7.3 by Padraig O'Sullivan
Used std::string for the type in Select_Lex instead of char *.
278
                                     keylen_str_buf;
1240.7.1 by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes
279
        item_list.push_back(new Item_string(keylen_str_buf,
280
                                            length,
281
                                            system_charset_info));
282
        item_list.push_back(item_null);
283
      }
284
      else if (tab->select && tab->select->quick)
285
      {
286
        tab->select->quick->add_keys_and_lengths(&tmp2, &tmp3);
2170.4.3 by Stewart Smith
convert tmp2 in explain_plan to std::string instead of char[] buf and String, consequently also convert add_keys_and_length to deal with std::string for key_names parameter
287
        item_list.push_back(new Item_string(tmp2.c_str(),tmp2.length(),cs));
2170.4.4 by Stewart Smith
tmp3 String to std::string in explain_plan (and used_lengths parameter to add_keys_and_lengths
288
        item_list.push_back(new Item_string(tmp3.c_str(),tmp3.length(),cs));
1240.7.1 by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes
289
        item_list.push_back(item_null);
290
      }
291
      else
292
      {
293
        item_list.push_back(item_null);
294
        item_list.push_back(item_null);
295
        item_list.push_back(item_null);
296
      }
297
298
      /* Add "rows" field to item_list. */
299
      double examined_rows;
300
      if (tab->select && tab->select->quick)
1240.7.3 by Padraig O'Sullivan
Used std::string for the type in Select_Lex instead of char *.
301
      {
2160.1.3 by Olaf van der Spek
refactor rows2double
302
        examined_rows= tab->select->quick->records;
1240.7.3 by Padraig O'Sullivan
Used std::string for the type in Select_Lex instead of char *.
303
      }
1240.7.1 by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes
304
      else if (tab->type == AM_NEXT || tab->type == AM_ALL)
1240.7.3 by Padraig O'Sullivan
Used std::string for the type in Select_Lex instead of char *.
305
      {
2160.1.3 by Olaf van der Spek
refactor rows2double
306
        examined_rows= tab->limit ? tab->limit : tab->table->cursor->records();
1240.7.3 by Padraig O'Sullivan
Used std::string for the type in Select_Lex instead of char *.
307
      }
1240.7.1 by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes
308
      else
309
      {
310
        optimizer::Position cur_pos= join->getPosFromOptimalPlan(i);
311
        examined_rows= cur_pos.getFanout();
312
      }
313
314
      item_list.push_back(new Item_int((int64_t) (uint64_t) examined_rows,
1240.7.3 by Padraig O'Sullivan
Used std::string for the type in Select_Lex instead of char *.
315
                                       MY_INT64_NUM_DECIMAL_DIGITS));
1240.7.1 by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes
316
317
      /* Add "filtered" field to item_list. */
2227.4.8 by Olaf van der Spek
Session::lex()
318
      if (join->session->lex().describe & DESCRIBE_EXTENDED)
1240.7.1 by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes
319
      {
320
        float f= 0.0;
321
        if (examined_rows)
322
        {
323
          optimizer::Position cur_pos= join->getPosFromOptimalPlan(i);
1240.7.3 by Padraig O'Sullivan
Used std::string for the type in Select_Lex instead of char *.
324
          f= static_cast<float>(100.0 * cur_pos.getFanout() / examined_rows);
1240.7.1 by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes
325
        }
326
        item_list.push_back(new Item_float(f, 2));
327
      }
328
329
      /* Build "Extra" field and add it to item_list. */
330
      bool key_read= table->key_read;
331
      if ((tab->type == AM_NEXT || tab->type == AM_CONST) &&
332
          table->covering_keys.test(tab->index))
333
        key_read= 1;
1240.7.6 by Padraig O'Sullivan
Resolved one last conflict after the merge from trunk.
334
      if (quick_type == optimizer::QuickSelectInterface::QS_TYPE_ROR_INTERSECT &&
1240.7.8 by Padraig O'Sullivan
Resolved some conflicts after merging with build.
335
          ! ((optimizer::QuickRorIntersectSelect *) tab->select->quick)->need_to_fetch_row)
1240.7.1 by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes
336
        key_read= 1;
337
338
      if (tab->info)
339
        item_list.push_back(new Item_string(tab->info,strlen(tab->info),cs));
340
      else if (tab->packed_info & TAB_INFO_HAVE_VALUE)
341
      {
342
        if (tab->packed_info & TAB_INFO_USING_INDEX)
2170.4.5 by Stewart Smith
convert explain_plan extra String to std::string. This means that add_info_string() also gets converted to std::string
343
          extra.append("; Using index");
1240.7.1 by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes
344
        if (tab->packed_info & TAB_INFO_USING_WHERE)
2170.4.5 by Stewart Smith
convert explain_plan extra String to std::string. This means that add_info_string() also gets converted to std::string
345
          extra.append("; Using where");
1240.7.1 by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes
346
        if (tab->packed_info & TAB_INFO_FULL_SCAN_ON_NULL)
2170.4.5 by Stewart Smith
convert explain_plan extra String to std::string. This means that add_info_string() also gets converted to std::string
347
          extra.append("; Full scan on NULL key");
348
        if (extra.length())
349
          extra.erase(0, 2);        /* Skip initial "; "*/
350
        item_list.push_back(new Item_string(extra.c_str(), extra.length(), cs));
1240.7.1 by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes
351
      }
352
      else
353
      {
1240.7.6 by Padraig O'Sullivan
Resolved one last conflict after the merge from trunk.
354
        if (quick_type == optimizer::QuickSelectInterface::QS_TYPE_ROR_UNION ||
355
            quick_type == optimizer::QuickSelectInterface::QS_TYPE_ROR_INTERSECT ||
356
            quick_type == optimizer::QuickSelectInterface::QS_TYPE_INDEX_MERGE)
1240.7.1 by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes
357
        {
2170.4.5 by Stewart Smith
convert explain_plan extra String to std::string. This means that add_info_string() also gets converted to std::string
358
          extra.append("; Using ");
1240.7.1 by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes
359
          tab->select->quick->add_info_string(&extra);
360
        }
361
        if (tab->select)
362
        {
363
          if (tab->use_quick == 2)
364
          {
365
            /*
366
             * To print out the bitset in tab->keys, we go through
367
             * it 32 bits at a time. We need to do this to ensure
368
             * that the to_ulong() method will not throw an
369
             * out_of_range exception at runtime which would happen
370
             * if the bitset we were working with was larger than 64
371
             * bits on a 64-bit platform (for example).
372
             */
373
            stringstream s, w;
374
            string str;
375
            w << tab->keys;
376
            w >> str;
377
            for (uint32_t pos= 0; pos < tab->keys.size(); pos+= 32)
378
            {
379
              bitset<32> tmp(str, pos, 32);
380
              if (tmp.any())
381
                s << uppercase << hex << tmp.to_ulong();
382
            }
2170.4.5 by Stewart Smith
convert explain_plan extra String to std::string. This means that add_info_string() also gets converted to std::string
383
            extra.append("; Range checked for each record (index map: 0x");
1240.7.1 by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes
384
            extra.append(s.str().c_str());
2170.4.5 by Stewart Smith
convert explain_plan extra String to std::string. This means that add_info_string() also gets converted to std::string
385
            extra.append(")");
1240.7.1 by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes
386
          }
387
          else if (tab->select->cond)
388
          {
2170.4.5 by Stewart Smith
convert explain_plan extra String to std::string. This means that add_info_string() also gets converted to std::string
389
            extra.append("; Using where");
1240.7.1 by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes
390
          }
391
        }
392
        if (key_read)
393
        {
1240.7.6 by Padraig O'Sullivan
Resolved one last conflict after the merge from trunk.
394
          if (quick_type == optimizer::QuickSelectInterface::QS_TYPE_GROUP_MIN_MAX)
2170.4.5 by Stewart Smith
convert explain_plan extra String to std::string. This means that add_info_string() also gets converted to std::string
395
            extra.append("; Using index for group-by");
1240.7.1 by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes
396
          else
2170.4.5 by Stewart Smith
convert explain_plan extra String to std::string. This means that add_info_string() also gets converted to std::string
397
            extra.append("; Using index");
1240.7.1 by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes
398
        }
399
        if (table->reginfo.not_exists_optimize)
2170.4.5 by Stewart Smith
convert explain_plan extra String to std::string. This means that add_info_string() also gets converted to std::string
400
          extra.append("; Not exists");
1240.7.1 by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes
401
402
        if (need_tmp_table)
403
        {
404
          need_tmp_table=0;
2170.4.5 by Stewart Smith
convert explain_plan extra String to std::string. This means that add_info_string() also gets converted to std::string
405
          extra.append("; Using temporary");
1240.7.1 by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes
406
        }
407
        if (need_order)
408
        {
409
          need_order=0;
2170.4.5 by Stewart Smith
convert explain_plan extra String to std::string. This means that add_info_string() also gets converted to std::string
410
          extra.append("; Using filesort");
1240.7.1 by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes
411
        }
412
        if (distinct & test_all_bits(used_tables,session->used_tables))
2170.4.5 by Stewart Smith
convert explain_plan extra String to std::string. This means that add_info_string() also gets converted to std::string
413
          extra.append("; Distinct");
1240.7.1 by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes
414
415
        if (tab->insideout_match_tab)
416
        {
2170.4.5 by Stewart Smith
convert explain_plan extra String to std::string. This means that add_info_string() also gets converted to std::string
417
          extra.append("; LooseScan");
1240.7.1 by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes
418
        }
419
420
        for (uint32_t part= 0; part < tab->ref.key_parts; part++)
421
        {
422
          if (tab->ref.cond_guards[part])
423
          {
2170.4.5 by Stewart Smith
convert explain_plan extra String to std::string. This means that add_info_string() also gets converted to std::string
424
            extra.append("; Full scan on NULL key");
1240.7.1 by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes
425
            break;
426
          }
427
        }
428
429
        if (i > 0 && tab[-1].next_select == sub_select_cache)
2170.4.5 by Stewart Smith
convert explain_plan extra String to std::string. This means that add_info_string() also gets converted to std::string
430
          extra.append("; Using join buffer");
1240.7.1 by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes
431
2170.4.5 by Stewart Smith
convert explain_plan extra String to std::string. This means that add_info_string() also gets converted to std::string
432
        if (extra.length())
433
          extra.erase(0, 2);
434
        item_list.push_back(new Item_string(extra.c_str(), extra.length(), cs));
1240.7.1 by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes
435
      }
436
      // For next iteration
437
      used_tables|=table->map;
438
      if (result->send_data(item_list))
439
        join->error= 1;
440
    }
441
  }
442
  for (Select_Lex_Unit *unit= join->select_lex->first_inner_unit();
443
      unit;
444
      unit= unit->next_unit())
445
  {
446
    if (explainUnion(session, unit, result))
447
      return;
448
  }
449
  return;
450
}
451
452
bool optimizer::ExplainPlan::explainUnion(Session *session,
453
                                          Select_Lex_Unit *unit,
454
                                          select_result *result)
455
{
456
  bool res= false;
457
  Select_Lex *first= unit->first_select();
458
459
  for (Select_Lex *sl= first;
460
       sl;
461
       sl= sl->next_select())
462
  {
463
    // drop UNCACHEABLE_EXPLAIN, because it is for internal usage only
1858.1.1 by Padraig O'Sullivan
Replaced a uint8_t member with a standard bitset since it was being used as a bitset....
464
    sl->uncacheable.reset(UNCACHEABLE_EXPLAIN);
2227.4.8 by Olaf van der Spek
Session::lex()
465
    if (&session->lex().select_lex == sl)
1240.7.2 by Padraig O'Sullivan
Updated the explainUnion method. I'm all for using the ? conditional statement but when it is nested
466
    {
467
      if (sl->first_inner_unit() || sl->next_select())
468
      {
1237.13.30 by Padraig O'Sullivan
Corrected a valgrind warning due to using std::string in the Select_Lex class whose memory is
469
        sl->type= optimizer::ST_PRIMARY;
1240.7.2 by Padraig O'Sullivan
Updated the explainUnion method. I'm all for using the ? conditional statement but when it is nested
470
      }
471
      else
472
      {
1237.13.30 by Padraig O'Sullivan
Corrected a valgrind warning due to using std::string in the Select_Lex class whose memory is
473
        sl->type= optimizer::ST_SIMPLE;
1240.7.2 by Padraig O'Sullivan
Updated the explainUnion method. I'm all for using the ? conditional statement but when it is nested
474
      }
475
    }
476
    else
477
    {
478
      if (sl == first)
479
      {
480
        if (sl->linkage == DERIVED_TABLE_TYPE)
481
        {
1237.13.30 by Padraig O'Sullivan
Corrected a valgrind warning due to using std::string in the Select_Lex class whose memory is
482
          sl->type= optimizer::ST_DERIVED;
1240.7.2 by Padraig O'Sullivan
Updated the explainUnion method. I'm all for using the ? conditional statement but when it is nested
483
        }
484
        else
485
        {
1858.1.1 by Padraig O'Sullivan
Replaced a uint8_t member with a standard bitset since it was being used as a bitset....
486
          if (sl->uncacheable.test(UNCACHEABLE_DEPENDENT))
1240.7.2 by Padraig O'Sullivan
Updated the explainUnion method. I'm all for using the ? conditional statement but when it is nested
487
          {
1237.13.30 by Padraig O'Sullivan
Corrected a valgrind warning due to using std::string in the Select_Lex class whose memory is
488
            sl->type= optimizer::ST_DEPENDENT_SUBQUERY;
1240.7.2 by Padraig O'Sullivan
Updated the explainUnion method. I'm all for using the ? conditional statement but when it is nested
489
          }
490
          else
491
          {
1858.1.1 by Padraig O'Sullivan
Replaced a uint8_t member with a standard bitset since it was being used as a bitset....
492
            if (sl->uncacheable.any())
1240.7.2 by Padraig O'Sullivan
Updated the explainUnion method. I'm all for using the ? conditional statement but when it is nested
493
            {
1237.13.30 by Padraig O'Sullivan
Corrected a valgrind warning due to using std::string in the Select_Lex class whose memory is
494
              sl->type= optimizer::ST_UNCACHEABLE_SUBQUERY;
1240.7.2 by Padraig O'Sullivan
Updated the explainUnion method. I'm all for using the ? conditional statement but when it is nested
495
            }
496
            else
497
            {
1237.13.30 by Padraig O'Sullivan
Corrected a valgrind warning due to using std::string in the Select_Lex class whose memory is
498
              sl->type= optimizer::ST_SUBQUERY;
1240.7.2 by Padraig O'Sullivan
Updated the explainUnion method. I'm all for using the ? conditional statement but when it is nested
499
            }
500
          }
501
        }
502
      }
503
      else
504
      {
1858.1.1 by Padraig O'Sullivan
Replaced a uint8_t member with a standard bitset since it was being used as a bitset....
505
        if (sl->uncacheable.test(UNCACHEABLE_DEPENDENT))
1240.7.2 by Padraig O'Sullivan
Updated the explainUnion method. I'm all for using the ? conditional statement but when it is nested
506
        {
1237.13.30 by Padraig O'Sullivan
Corrected a valgrind warning due to using std::string in the Select_Lex class whose memory is
507
          sl->type= optimizer::ST_DEPENDENT_UNION;
1240.7.2 by Padraig O'Sullivan
Updated the explainUnion method. I'm all for using the ? conditional statement but when it is nested
508
        }
509
        else
510
        {
1858.1.1 by Padraig O'Sullivan
Replaced a uint8_t member with a standard bitset since it was being used as a bitset....
511
          if (sl->uncacheable.any())
1240.7.2 by Padraig O'Sullivan
Updated the explainUnion method. I'm all for using the ? conditional statement but when it is nested
512
          {
1237.13.30 by Padraig O'Sullivan
Corrected a valgrind warning due to using std::string in the Select_Lex class whose memory is
513
            sl->type= optimizer::ST_UNCACHEABLE_UNION;
1240.7.2 by Padraig O'Sullivan
Updated the explainUnion method. I'm all for using the ? conditional statement but when it is nested
514
          }
515
          else
516
          {
1237.13.30 by Padraig O'Sullivan
Corrected a valgrind warning due to using std::string in the Select_Lex class whose memory is
517
            sl->type= optimizer::ST_UNION;
1240.7.2 by Padraig O'Sullivan
Updated the explainUnion method. I'm all for using the ? conditional statement but when it is nested
518
          }
519
        }
520
      }
521
    }
1240.7.1 by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes
522
    sl->options|= SELECT_DESCRIBE;
523
  }
1240.7.2 by Padraig O'Sullivan
Updated the explainUnion method. I'm all for using the ? conditional statement but when it is nested
524
1240.7.1 by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes
525
  if (unit->is_union())
526
  {
1240.7.2 by Padraig O'Sullivan
Updated the explainUnion method. I'm all for using the ? conditional statement but when it is nested
527
    unit->fake_select_lex->select_number= UINT_MAX; // just for initialization
1237.13.30 by Padraig O'Sullivan
Corrected a valgrind warning due to using std::string in the Select_Lex class whose memory is
528
    unit->fake_select_lex->type= optimizer::ST_UNION_RESULT;
1240.7.1 by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes
529
    unit->fake_select_lex->options|= SELECT_DESCRIBE;
530
    if (! (res= unit->prepare(session, result, SELECT_NO_UNLOCK | SELECT_DESCRIBE)))
1240.7.2 by Padraig O'Sullivan
Updated the explainUnion method. I'm all for using the ? conditional statement but when it is nested
531
    {
1240.7.1 by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes
532
      res= unit->exec();
1240.7.2 by Padraig O'Sullivan
Updated the explainUnion method. I'm all for using the ? conditional statement but when it is nested
533
    }
1240.7.1 by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes
534
    res|= unit->cleanup();
535
  }
536
  else
537
  {
2227.4.8 by Olaf van der Spek
Session::lex()
538
    session->lex().current_select= first;
1240.7.1 by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes
539
    unit->set_limit(unit->global_parameters);
2026.2.1 by Monty Taylor
Renamed things prefixed mysql_ or mysqld_
540
    res= select_query(session, 
1240.7.1 by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes
541
                      &first->ref_pointer_array,
542
                      (TableList*) first->table_list.first,
543
                      first->with_wild, 
544
                      first->item_list,
545
                      first->where,
546
                      first->order_list.elements + first->group_list.elements,
1892.3.3 by tdavies
struct order_st changed and renamed to c++ class named:Order
547
                      (Order*) first->order_list.first,
548
                      (Order*) first->group_list.first,
1240.7.1 by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes
549
                      first->having,
550
                      first->options | session->options | SELECT_DESCRIBE,
551
                      result, 
552
                      unit, 
553
                      first);
554
  }
555
  return (res || session->is_error());
556
}
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
557
558
} /* namespace drizzled */