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