~maria-captains/maria/5.5-explain-analyze

« back to all changes in this revision

Viewing changes to sql/sql_class.cc

  • Committer: Sergey Petrunya
  • Date: 2012-09-03 15:11:24 UTC
  • Revision ID: psergey@askmonty.org-20120903151124-s1y9vrz3k4ezy642
MDEV-406: EXPLAIN ANALYZE 
- First code, it is possible to get the data for joins/unions
- Numbers for join buffering are likely to be incorrect
- Same for subqueries (what should 'loops' show?)

Show diffs side-by-side

added added

removed removed

Lines of Context:
2015
2015
int THD::send_explain_fields(select_result *result)
2016
2016
{
2017
2017
  List<Item> field_list;
2018
 
  make_explain_field_list(field_list);
 
2018
  make_explain_field_list(field_list, FALSE /* not EXPLAIN ANALYZE */);
2019
2019
  return (result->send_result_set_metadata(field_list,
2020
2020
                                           Protocol::SEND_NUM_ROWS | 
2021
2021
                                           Protocol::SEND_EOF));
2025
2025
/*
2026
2026
  Populate the provided field_list with EXPLAIN output columns.
2027
2027
  this->lex->describe has the EXPLAIN flags
 
2028
 
 
2029
  Column sets in this function must be kept in sync with
 
2030
  - print_fake_select_lex_join
 
2031
  - JOIN::print_explain
 
2032
 
2028
2033
*/
2029
2034
 
2030
 
void THD::make_explain_field_list(List<Item> &field_list)
 
2035
void THD::make_explain_field_list(List<Item> &field_list, bool explain_analyze)
2031
2036
{
2032
2037
  Item *item;
2033
2038
  CHARSET_INFO *cs= system_charset_info;
2058
2063
                                                  NAME_CHAR_LEN*MAX_REF_PARTS,
2059
2064
                                                  cs));
2060
2065
  item->maybe_null=1;
 
2066
  if (explain_analyze)
 
2067
  {
 
2068
    field_list.push_back(item= new Item_return_int("loops", 10,
 
2069
                                                 MYSQL_TYPE_LONGLONG));
 
2070
    item->maybe_null=1;
 
2071
  }
 
2072
  
2061
2073
  field_list.push_back(item= new Item_return_int("rows", 10,
2062
2074
                                                 MYSQL_TYPE_LONGLONG));
2063
 
  if (lex->describe & DESCRIBE_EXTENDED)
 
2075
  item->maybe_null=1;
 
2076
 
 
2077
  if (explain_analyze)
 
2078
  {
 
2079
    field_list.push_back(item= new Item_return_int("r_rows", 10,
 
2080
                                                   MYSQL_TYPE_LONGLONG));
 
2081
    item->maybe_null=1;
 
2082
  }
 
2083
 
 
2084
  if (lex->describe & DESCRIBE_EXTENDED || explain_analyze)
2064
2085
  {
2065
2086
    field_list.push_back(item= new Item_float("filtered", 0.1234, 2, 4));
2066
2087
    item->maybe_null=1;
2067
2088
  }
2068
 
  item->maybe_null= 1;
 
2089
 
 
2090
  if (explain_analyze)
 
2091
  {
 
2092
    field_list.push_back(item= new Item_float("r_filtered", 0.1234, 2, 4));
 
2093
    item->maybe_null=1;
 
2094
  }
 
2095
 
2069
2096
  field_list.push_back(new Item_empty_string("Extra", 255, cs));
2070
2097
}
2071
2098
 
2227
2254
bool select_send::send_result_set_metadata(List<Item> &list, uint flags)
2228
2255
{
2229
2256
  bool res;
 
2257
  
 
2258
  /* Buypass for SHOW EXPLAIN */
 
2259
  if (discard_data)
 
2260
    return false;
 
2261
 
2230
2262
  if (!(res= thd->protocol->send_result_set_metadata(&list, flags)))
2231
2263
    is_result_set_started= 1;
2232
2264
  return res;
2287
2319
  ha_release_temporary_latches(thd);
2288
2320
 
2289
2321
  protocol->prepare_for_resend();
2290
 
  if (protocol->send_result_set_row(&items))
 
2322
  if (!discard_data && protocol->send_result_set_row(&items))
2291
2323
  {
2292
2324
    protocol->remove_last_row();
2293
2325
    DBUG_RETURN(TRUE);
2295
2327
 
2296
2328
  thd->sent_row_count++;
2297
2329
 
2298
 
  if (thd->vio_ok())
 
2330
  if (!discard_data && thd->vio_ok())
2299
2331
    DBUG_RETURN(protocol->write());
2300
2332
 
2301
2333
  DBUG_RETURN(0);
2323
2355
}
2324
2356
 
2325
2357
 
 
2358
//////////////////////////////////////////////////////////////////////////////
 
2359
// psergey-explain-analyze: select_result_basic_explain_buffer implementation
 
2360
/*
 
2361
  Save the data being sent in our internal buffer.
 
2362
*/
 
2363
 
 
2364
int select_result_basic_explain_buffer::send_data(List<Item> &items)
 
2365
{
 
2366
  List_iterator_fast<Item> li(items);
 
2367
  char buff[MAX_FIELD_WIDTH];
 
2368
  String buffer(buff, sizeof(buff), &my_charset_bin);
 
2369
  DBUG_ENTER("select_send::send_data");
 
2370
 
 
2371
  protocol->prepare_for_resend();
 
2372
  Item *item;
 
2373
  while ((item=li++))
 
2374
  {
 
2375
    if (item->send(protocol, &buffer))
 
2376
    {
 
2377
      protocol->free();                         // Free used buffer
 
2378
      my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0));
 
2379
      break;
 
2380
    }
 
2381
    /*
 
2382
      Reset buffer to its original state, as it may have been altered in
 
2383
      Item::send().
 
2384
    */
 
2385
    buffer.set(buff, sizeof(buff), &my_charset_bin);
 
2386
  }
 
2387
 
 
2388
  if (thd->is_error())
 
2389
  {
 
2390
    protocol->remove_last_row();
 
2391
    DBUG_RETURN(1);
 
2392
  }
 
2393
  /* 
 
2394
    Instead of calling protocol->write(), steal the packet and put it to our
 
2395
    buffer 
 
2396
  */
 
2397
  const char *packet_data;
 
2398
  size_t len;
 
2399
  protocol->get_packet(&packet_data, &len);
 
2400
 
 
2401
  String *s= new (thd->mem_root) String;
 
2402
  s->append(packet_data, len);
 
2403
  data_rows->push_back(s);
 
2404
  protocol->remove_last_row(); // <-- this does nothing. Do we need it?
 
2405
                               // prepare_for_resend() will wipe out the packet
 
2406
  DBUG_RETURN(0);
 
2407
}
 
2408
 
 
2409
 
 
2410
/* Write the saved resultset to the client (via this->protocol) and free it. */
 
2411
#if 0
 
2412
void select_result_basic_explain_buffer::flush_data()
 
2413
{
 
2414
  List_iterator<String> it(*data_rows);
 
2415
  String *str;
 
2416
  while ((str= it++))
 
2417
  {
 
2418
    protocol->set_packet(str->ptr(), str->length());
 
2419
    protocol->write();
 
2420
    delete str;
 
2421
  }
 
2422
  data_rows->empty();
 
2423
}
 
2424
#endif
 
2425
 
 
2426
/* Free the accumulated resultset */
 
2427
 
 
2428
void select_result_basic_explain_buffer::discard_data()
 
2429
{
 
2430
  List_iterator<String> it(*data_rows);
 
2431
  String *str;
 
2432
  while ((str= it++))
 
2433
  {
 
2434
    delete str;
 
2435
  }
 
2436
  data_rows->empty();
 
2437
}
 
2438
 
 
2439
List<String> *select_result_basic_explain_buffer::remove_stored_data()
 
2440
{
 
2441
  List<String> *ptr= data_rows;
 
2442
  data_rows= new List<String>;
 
2443
  return ptr;
 
2444
}
 
2445
 
 
2446
//////////////////////////////////////////////////////////////////////////////
 
2447
 
2326
2448
/************************************************************************
2327
2449
  Handling writing to file
2328
2450
************************************************************************/