~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/optimizer/explain_plan.cc

  • Committer: patrick crews
  • Date: 2011-06-08 03:02:27 UTC
  • mto: This revision was merged to the branch mainline in revision 2329.
  • Revision ID: gleebix@gmail.com-20110608030227-updkyv2652zvfajc
Initial voodoo worked to give us a crashme mode.  Need docs still

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
3
 *
4
 
 *  Copyright (C) 2008-2009 Sun Microsystems
 
4
 *  Copyright (C) 2008-2009 Sun Microsystems, Inc.
5
5
 *
6
6
 *  This program is free software; you can redistribute it and/or modify
7
7
 *  it under the terms of the GNU General Public License as published by
17
17
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18
18
 */
19
19
 
20
 
#include "config.h"
21
 
#include "drizzled/session.h"
22
 
#include "drizzled/item/uint.h"
23
 
#include "drizzled/item/float.h"
24
 
#include "drizzled/item/string.h"
25
 
#include "drizzled/optimizer/explain_plan.h"
26
 
#include "drizzled/optimizer/position.h"
27
 
#include "drizzled/optimizer/quick_ror_intersect_select.h"
28
 
#include "drizzled/optimizer/range.h"
29
 
#include "drizzled/sql_select.h"
30
 
#include "drizzled/join.h"
31
 
#include "drizzled/internal/m_string.h"
 
20
#include <config.h>
 
21
 
 
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>
 
33
#include <drizzled/select_result.h>
 
34
#include <drizzled/sql_lex.h>
32
35
 
33
36
#include <cstdio>
34
37
#include <string>
73
76
 
74
77
void optimizer::ExplainPlan::printPlan()
75
78
{
76
 
  List<Item> field_list;
77
79
  List<Item> item_list;
78
80
  Session *session= join->session;
79
81
  select_result *result= join->result;
80
82
  Item *item_null= new Item_null();
81
 
  const CHARSET_INFO * const cs= system_charset_info;
 
83
  const charset_info_st * const cs= system_charset_info;
82
84
  int quick_type;
83
85
  /* Don't log this into the slow query log */
84
86
  session->server_status&= ~(SERVER_QUERY_NO_INDEX_USED | SERVER_QUERY_NO_GOOD_INDEX_USED);
98
100
    for (uint32_t i= 0; i < 7; i++)
99
101
      item_list.push_back(item_null);
100
102
 
101
 
    if (join->session->lex->describe & DESCRIBE_EXTENDED)
 
103
    if (join->session->lex().describe & DESCRIBE_EXTENDED)
102
104
      item_list.push_back(item_null);
103
105
 
104
106
    item_list.push_back(new Item_string(message,strlen(message),cs));
115
117
       appreciated :)
116
118
     */
117
119
    char table_name_buffer[NAME_LEN];
118
 
    item_list.empty();
 
120
    item_list.clear();
119
121
    /* id */
120
122
    item_list.push_back(new Item_null);
121
123
    /* select_type */
158
160
    /* ref */
159
161
    item_list.push_back(item_null);
160
162
    /* in_rows */
161
 
    if (join->session->lex->describe & DESCRIBE_EXTENDED)
 
163
    if (join->session->lex().describe & DESCRIBE_EXTENDED)
162
164
      item_list.push_back(item_null);
163
165
    /* rows */
164
166
    item_list.push_back(item_null);
180
182
    {
181
183
      JoinTable *tab= join->join_tab + i;
182
184
      Table *table= tab->table;
183
 
      char buff[512];
184
 
      char buff1[512], buff2[512], buff3[512];
185
185
      char keylen_str_buf[64];
186
 
      String extra(buff, sizeof(buff),cs);
 
186
      string extra;
187
187
      char table_name_buffer[NAME_LEN];
188
 
      String tmp1(buff1,sizeof(buff1),cs);
189
 
      String tmp2(buff2,sizeof(buff2),cs);
190
 
      String tmp3(buff3,sizeof(buff3),cs);
191
 
      extra.length(0);
192
 
      tmp1.length(0);
193
 
      tmp2.length(0);
194
 
      tmp3.length(0);
 
188
      string tmp1;
 
189
      string tmp2;
 
190
      string tmp3;
195
191
 
196
192
      quick_type= -1;
197
 
      item_list.empty();
 
193
      item_list.clear();
198
194
      /* id */
199
195
      item_list.push_back(new Item_uint((uint32_t)
200
196
            join->select_lex->select_number));
241
237
          if (tab->keys.test(j))
242
238
          {
243
239
            if (tmp1.length())
244
 
              tmp1.append(',');
 
240
              tmp1.append(",");
245
241
            tmp1.append(table->key_info[j].name,
246
 
                        strlen(table->key_info[j].name),
247
 
                        system_charset_info);
 
242
                        strlen(table->key_info[j].name));
248
243
          }
249
244
        }
250
245
      }
251
246
      if (tmp1.length())
252
 
        item_list.push_back(new Item_string(tmp1.ptr(),tmp1.length(),cs));
 
247
        item_list.push_back(new Item_string(tmp1.c_str(),tmp1.length(),cs));
253
248
      else
254
249
        item_list.push_back(item_null);
255
250
 
268
263
        for (StoredKey **ref= tab->ref.key_copy; *ref; ref++)
269
264
        {
270
265
          if (tmp2.length())
271
 
            tmp2.append(',');
272
 
          tmp2.append((*ref)->name(), 
273
 
                       strlen((*ref)->name()),
274
 
                       system_charset_info);
 
266
            tmp2.append(",");
 
267
          tmp2.append((*ref)->name(),
 
268
                      strlen((*ref)->name()));
275
269
        }
276
 
        item_list.push_back(new Item_string(tmp2.ptr(),tmp2.length(),cs));
 
270
        item_list.push_back(new Item_string(tmp2.c_str(),tmp2.length(),cs));
277
271
      }
278
272
      else if (tab->type == AM_NEXT)
279
273
      {
290
284
      else if (tab->select && tab->select->quick)
291
285
      {
292
286
        tab->select->quick->add_keys_and_lengths(&tmp2, &tmp3);
293
 
        item_list.push_back(new Item_string(tmp2.ptr(),tmp2.length(),cs));
294
 
        item_list.push_back(new Item_string(tmp3.ptr(),tmp3.length(),cs));
 
287
        item_list.push_back(new Item_string(tmp2.c_str(),tmp2.length(),cs));
 
288
        item_list.push_back(new Item_string(tmp3.c_str(),tmp3.length(),cs));
295
289
        item_list.push_back(item_null);
296
290
      }
297
291
      else
305
299
      double examined_rows;
306
300
      if (tab->select && tab->select->quick)
307
301
      {
308
 
        examined_rows= rows2double(tab->select->quick->records);
 
302
        examined_rows= tab->select->quick->records;
309
303
      }
310
304
      else if (tab->type == AM_NEXT || tab->type == AM_ALL)
311
305
      {
312
 
        examined_rows= rows2double(tab->limit ? tab->limit :
313
 
                                                tab->table->cursor->records());
 
306
        examined_rows= tab->limit ? tab->limit : tab->table->cursor->records();
314
307
      }
315
308
      else
316
309
      {
322
315
                                       MY_INT64_NUM_DECIMAL_DIGITS));
323
316
 
324
317
      /* Add "filtered" field to item_list. */
325
 
      if (join->session->lex->describe & DESCRIBE_EXTENDED)
 
318
      if (join->session->lex().describe & DESCRIBE_EXTENDED)
326
319
      {
327
320
        float f= 0.0;
328
321
        if (examined_rows)
347
340
      else if (tab->packed_info & TAB_INFO_HAVE_VALUE)
348
341
      {
349
342
        if (tab->packed_info & TAB_INFO_USING_INDEX)
350
 
          extra.append(STRING_WITH_LEN("; Using index"));
 
343
          extra.append("; Using index");
351
344
        if (tab->packed_info & TAB_INFO_USING_WHERE)
352
 
          extra.append(STRING_WITH_LEN("; Using where"));
 
345
          extra.append("; Using where");
353
346
        if (tab->packed_info & TAB_INFO_FULL_SCAN_ON_NULL)
354
 
          extra.append(STRING_WITH_LEN("; Full scan on NULL key"));
355
 
        /* Skip initial "; "*/
356
 
        const char *str= extra.ptr();
357
 
        uint32_t len= extra.length();
358
 
        if (len)
359
 
        {
360
 
          str += 2;
361
 
          len -= 2;
362
 
        }
363
 
        item_list.push_back(new Item_string(str, len, cs));
 
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));
364
351
      }
365
352
      else
366
353
      {
367
 
        uint32_t keyno= MAX_KEY;
368
 
        if (tab->ref.key_parts)
369
 
          keyno= tab->ref.key;
370
 
        else if (tab->select && tab->select->quick)
371
 
          keyno = tab->select->quick->index;
372
 
 
373
354
        if (quick_type == optimizer::QuickSelectInterface::QS_TYPE_ROR_UNION ||
374
355
            quick_type == optimizer::QuickSelectInterface::QS_TYPE_ROR_INTERSECT ||
375
356
            quick_type == optimizer::QuickSelectInterface::QS_TYPE_INDEX_MERGE)
376
357
        {
377
 
          extra.append(STRING_WITH_LEN("; Using "));
 
358
          extra.append("; Using ");
378
359
          tab->select->quick->add_info_string(&extra);
379
360
        }
380
361
        if (tab->select)
399
380
              if (tmp.any())
400
381
                s << uppercase << hex << tmp.to_ulong();
401
382
            }
402
 
            extra.append(STRING_WITH_LEN("; Range checked for each "
403
 
                  "record (index map: 0x"));
 
383
            extra.append("; Range checked for each record (index map: 0x");
404
384
            extra.append(s.str().c_str());
405
 
            extra.append(')');
 
385
            extra.append(")");
406
386
          }
407
387
          else if (tab->select->cond)
408
388
          {
409
 
            extra.append(STRING_WITH_LEN("; Using where"));
 
389
            extra.append("; Using where");
410
390
          }
411
391
        }
412
392
        if (key_read)
413
393
        {
414
394
          if (quick_type == optimizer::QuickSelectInterface::QS_TYPE_GROUP_MIN_MAX)
415
 
            extra.append(STRING_WITH_LEN("; Using index for group-by"));
 
395
            extra.append("; Using index for group-by");
416
396
          else
417
 
            extra.append(STRING_WITH_LEN("; Using index"));
 
397
            extra.append("; Using index");
418
398
        }
419
399
        if (table->reginfo.not_exists_optimize)
420
 
          extra.append(STRING_WITH_LEN("; Not exists"));
 
400
          extra.append("; Not exists");
421
401
 
422
402
        if (need_tmp_table)
423
403
        {
424
404
          need_tmp_table=0;
425
 
          extra.append(STRING_WITH_LEN("; Using temporary"));
 
405
          extra.append("; Using temporary");
426
406
        }
427
407
        if (need_order)
428
408
        {
429
409
          need_order=0;
430
 
          extra.append(STRING_WITH_LEN("; Using filesort"));
 
410
          extra.append("; Using filesort");
431
411
        }
432
412
        if (distinct & test_all_bits(used_tables,session->used_tables))
433
 
          extra.append(STRING_WITH_LEN("; Distinct"));
 
413
          extra.append("; Distinct");
434
414
 
435
415
        if (tab->insideout_match_tab)
436
416
        {
437
 
          extra.append(STRING_WITH_LEN("; LooseScan"));
 
417
          extra.append("; LooseScan");
438
418
        }
439
419
 
440
420
        for (uint32_t part= 0; part < tab->ref.key_parts; part++)
441
421
        {
442
422
          if (tab->ref.cond_guards[part])
443
423
          {
444
 
            extra.append(STRING_WITH_LEN("; Full scan on NULL key"));
 
424
            extra.append("; Full scan on NULL key");
445
425
            break;
446
426
          }
447
427
        }
448
428
 
449
429
        if (i > 0 && tab[-1].next_select == sub_select_cache)
450
 
          extra.append(STRING_WITH_LEN("; Using join buffer"));
 
430
          extra.append("; Using join buffer");
451
431
 
452
 
        /* Skip initial "; "*/
453
 
        const char *str= extra.ptr();
454
 
        uint32_t len= extra.length();
455
 
        if (len)
456
 
        {
457
 
          str += 2;
458
 
          len -= 2;
459
 
        }
460
 
        item_list.push_back(new Item_string(str, len, cs));
 
432
        if (extra.length())
 
433
          extra.erase(0, 2);
 
434
        item_list.push_back(new Item_string(extra.c_str(), extra.length(), cs));
461
435
      }
462
436
      // For next iteration
463
437
      used_tables|=table->map;
488
462
  {
489
463
    // drop UNCACHEABLE_EXPLAIN, because it is for internal usage only
490
464
    sl->uncacheable.reset(UNCACHEABLE_EXPLAIN);
491
 
    if (&session->lex->select_lex == sl)
 
465
    if (&session->lex().select_lex == sl)
492
466
    {
493
467
      if (sl->first_inner_unit() || sl->next_select())
494
468
      {
561
535
  }
562
536
  else
563
537
  {
564
 
    session->lex->current_select= first;
 
538
    session->lex().current_select= first;
565
539
    unit->set_limit(unit->global_parameters);
566
 
    res= mysql_select(session, 
 
540
    res= select_query(session, 
567
541
                      &first->ref_pointer_array,
568
542
                      (TableList*) first->table_list.first,
569
543
                      first->with_wild,