~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_union.cc

  • Committer: Brian Aker
  • Date: 2009-04-27 14:36:40 UTC
  • Revision ID: brian@gaz-20090427143640-f6zjmtt9vm55qgm2
Patch on show processlist from  davi@apache.org

Show diffs side-by-side

added added

removed removed

Lines of Context:
19
19
*/
20
20
#include <drizzled/server_includes.h>
21
21
#include <drizzled/sql_select.h>
22
 
#include <drizzled/drizzled_error_messages.h>
 
22
#include <drizzled/error.h>
 
23
#include <drizzled/item/type_holder.h>
 
24
#include <drizzled/sql_base.h>
23
25
 
24
 
bool mysql_union(THD *thd,
25
 
                 LEX *lex __attribute__((unused)),
26
 
                 select_result *result,
27
 
                 SELECT_LEX_UNIT *unit, ulong setup_tables_done_option)
 
26
bool mysql_union(Session *session, LEX *, select_result *result,
 
27
                 Select_Lex_Unit *unit, uint64_t setup_tables_done_option)
28
28
{
29
29
  bool res;
30
 
  if (!(res= unit->prepare(thd, result, SELECT_NO_UNLOCK |
 
30
  if (!(res= unit->prepare(session, result, SELECT_NO_UNLOCK |
31
31
                           setup_tables_done_option)))
32
32
    res= unit->exec();
33
33
  if (res)
40
40
** store records in temporary table for UNION
41
41
***************************************************************************/
42
42
 
43
 
int select_union::prepare(List<Item> &list __attribute__((unused)),
44
 
                          SELECT_LEX_UNIT *u)
 
43
int select_union::prepare(List<Item> &, Select_Lex_Unit *u)
45
44
{
46
45
  unit= u;
47
46
  return 0;
56
55
    unit->offset_limit_cnt--;
57
56
    return 0;
58
57
  }
59
 
  fill_record(thd, table->field, values, 1);
60
 
  if (thd->is_error())
 
58
  fill_record(session, table->field, values, 1);
 
59
  if (session->is_error())
61
60
    return 1;
62
61
 
63
62
  if ((error= table->file->ha_write_row(table->record[0])))
64
63
  {
65
64
    /* create_myisam_from_heap will generate error if needed */
66
65
    if (table->file->is_fatal_error(error, HA_CHECK_DUP) &&
67
 
        create_myisam_from_heap(thd, table, tmp_table_param.start_recinfo, 
 
66
        create_myisam_from_heap(session, table, tmp_table_param.start_recinfo,
68
67
                                &tmp_table_param.recinfo, error, 1))
69
68
      return 1;
70
69
  }
94
93
 
95
94
  SYNOPSIS
96
95
    select_union::create_result_table()
97
 
      thd                thread handle
 
96
      session                thread handle
98
97
      column_types       a list of items used to define columns of the
99
98
                         temporary table
100
99
      is_union_distinct  if set, the temporary table will eliminate
113
112
*/
114
113
 
115
114
bool
116
 
select_union::create_result_table(THD *thd_arg, List<Item> *column_types,
 
115
select_union::create_result_table(Session *session_arg, List<Item> *column_types,
117
116
                                  bool is_union_distinct, uint64_t options,
118
117
                                  const char *table_alias,
119
118
                                  bool bit_fields_as_long)
123
122
  tmp_table_param.field_count= column_types->elements;
124
123
  tmp_table_param.bit_fields_as_long= bit_fields_as_long;
125
124
 
126
 
  if (! (table= create_tmp_table(thd_arg, &tmp_table_param, *column_types,
 
125
  if (! (table= create_tmp_table(session_arg, &tmp_table_param, *column_types,
127
126
                                 (order_st*) 0, is_union_distinct, 1,
128
127
                                 options, HA_POS_ERROR, (char*) table_alias)))
129
128
    return true;
153
152
  initialization procedures before fake_select_lex preparation()
154
153
 
155
154
  SYNOPSIS
156
 
    st_select_lex_unit::init_prepare_fake_select_lex()
157
 
    thd         - thread handler
 
155
    Select_Lex_Unit::init_prepare_fake_select_lex()
 
156
    session             - thread handler
158
157
 
159
158
  RETURN
160
159
    options of SELECT
161
160
*/
162
161
 
163
162
void
164
 
st_select_lex_unit::init_prepare_fake_select_lex(THD *thd_arg) 
 
163
Select_Lex_Unit::init_prepare_fake_select_lex(Session *session_arg)
165
164
{
166
 
  thd_arg->lex->current_select= fake_select_lex;
 
165
  session_arg->lex->current_select= fake_select_lex;
167
166
  fake_select_lex->table_list.link_in_list((unsigned char *)&result_table_list,
168
167
                                           (unsigned char **)
169
168
                                           &result_table_list.next_local);
170
 
  fake_select_lex->context.table_list= 
171
 
    fake_select_lex->context.first_name_resolution_table= 
 
169
  fake_select_lex->context.table_list=
 
170
    fake_select_lex->context.first_name_resolution_table=
172
171
    fake_select_lex->get_table_list();
173
172
 
174
173
  for (order_st *order= (order_st *) global_parameters->order_list.first;
186
185
}
187
186
 
188
187
 
189
 
bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
190
 
                                 uint32_t additional_options)
 
188
bool Select_Lex_Unit::prepare(Session *session_arg, select_result *sel_result,
 
189
                              uint64_t additional_options)
191
190
{
192
 
  SELECT_LEX *lex_select_save= thd_arg->lex->current_select;
193
 
  SELECT_LEX *sl, *first_sl= first_select();
 
191
  Select_Lex *lex_select_save= session_arg->lex->current_select;
 
192
  Select_Lex *sl, *first_sl= first_select();
194
193
  select_result *tmp_result;
195
194
  bool is_union_select;
196
195
  Table *empty_table= 0;
225
224
  }
226
225
  prepared= 1;
227
226
  saved_error= false;
228
 
  
229
 
  thd_arg->lex->current_select= sl= first_sl;
 
227
 
 
228
  session_arg->lex->current_select= sl= first_sl;
230
229
  found_rows_for_union= first_sl->options & OPTION_FOUND_ROWS;
231
230
  is_union_select= is_union() || fake_select_lex;
232
231
 
248
247
  {
249
248
    bool can_skip_order_by;
250
249
    sl->options|=  SELECT_NO_UNLOCK;
251
 
    JOIN *join= new JOIN(thd_arg, sl->item_list, 
252
 
                         sl->options | thd_arg->options | additional_options,
 
250
    JOIN *join= new JOIN(session_arg, sl->item_list,
 
251
                         sl->options | session_arg->options | additional_options,
253
252
                         tmp_result);
254
253
    /*
255
254
      setup_tables_done_option should be set only for very first SELECT,
261
260
    if (!join)
262
261
      goto err;
263
262
 
264
 
    thd_arg->lex->current_select= sl;
 
263
    session_arg->lex->current_select= sl;
265
264
 
266
265
    can_skip_order_by= is_union_select && !(sl->braces && sl->explicit_limit);
267
266
 
276
275
                               (order_st*) 0 : (order_st *)sl->order_list.first,
277
276
                               (order_st*) sl->group_list.first,
278
277
                               sl->having,
279
 
                               (is_union_select ? (order_st*) 0 :
280
 
                                (order_st*) thd_arg->lex->proc_list.first),
281
278
                               sl, this);
282
279
    /* There are no * in the statement anymore (for PS) */
283
280
    sl->with_wild= 0;
284
281
 
285
 
    if (saved_error || (saved_error= thd_arg->is_fatal_error))
 
282
    if (saved_error || (saved_error= session_arg->is_fatal_error))
286
283
      goto err;
287
284
    /*
288
285
      Use items list of underlaid select for derived tables to preserve
299
296
        field object without table.
300
297
      */
301
298
      assert(!empty_table);
302
 
      empty_table= (Table*) thd->calloc(sizeof(Table));
 
299
      empty_table= (Table*) session->calloc(sizeof(Table));
303
300
      types.empty();
304
301
      List_iterator_fast<Item> it(sl->item_list);
305
302
      Item *item_tmp;
306
303
      while ((item_tmp= it++))
307
304
      {
308
305
        /* Error's in 'new' will be detected after loop */
309
 
        types.push_back(new Item_type_holder(thd_arg, item_tmp));
 
306
        types.push_back(new Item_type_holder(session_arg, item_tmp));
310
307
      }
311
308
 
312
 
      if (thd_arg->is_fatal_error)
 
309
      if (session_arg->is_fatal_error)
313
310
        goto err; // out of memory
314
311
    }
315
312
    else
321
318
        goto err;
322
319
      }
323
320
      List_iterator_fast<Item> it(sl->item_list);
324
 
      List_iterator_fast<Item> tp(types);       
 
321
      List_iterator_fast<Item> tp(types);
325
322
      Item *type, *item_tmp;
326
323
      while ((type= tp++, item_tmp= it++))
327
324
      {
328
 
        if (((Item_type_holder*)type)->join_types(thd_arg, item_tmp))
 
325
        if (((Item_type_holder*)type)->join_types(session_arg, item_tmp))
329
326
          return(true);
330
327
      }
331
328
    }
350
347
        goto err;
351
348
      }
352
349
    }
353
 
    
354
 
    create_options= (first_sl->options | thd_arg->options |
 
350
 
 
351
    create_options= (first_sl->options | session_arg->options |
355
352
                     TMP_TABLE_ALL_COLUMNS);
356
353
 
357
 
    if (union_result->create_result_table(thd, &types, test(union_distinct),
 
354
    if (union_result->create_result_table(session, &types, test(union_distinct),
358
355
                                          create_options, "", false))
359
356
      goto err;
360
357
    memset(&result_table_list, 0, sizeof(result_table_list));
362
359
    result_table_list.table_name= result_table_list.alias= (char*) "union";
363
360
    result_table_list.table= table= union_result->table;
364
361
 
365
 
    thd_arg->lex->current_select= lex_select_save;
 
362
    session_arg->lex->current_select= lex_select_save;
366
363
    if (!item_list.elements)
367
364
    {
368
365
      saved_error= table->fill_item_list(&item_list);
379
376
    }
380
377
  }
381
378
 
382
 
  thd_arg->lex->current_select= lex_select_save;
 
379
  session_arg->lex->current_select= lex_select_save;
383
380
 
384
 
  return(saved_error || thd_arg->is_fatal_error);
 
381
  return(saved_error || session_arg->is_fatal_error);
385
382
 
386
383
err:
387
 
  thd_arg->lex->current_select= lex_select_save;
 
384
  session_arg->lex->current_select= lex_select_save;
388
385
  return(true);
389
386
}
390
387
 
391
388
 
392
 
bool st_select_lex_unit::exec()
 
389
bool Select_Lex_Unit::exec()
393
390
{
394
 
  SELECT_LEX *lex_select_save= thd->lex->current_select;
395
 
  SELECT_LEX *select_cursor=first_select();
 
391
  Select_Lex *lex_select_save= session->lex->current_select;
 
392
  Select_Lex *select_cursor=first_select();
396
393
  uint64_t add_rows=0;
397
394
  ha_rows examined_rows= 0;
398
395
 
399
396
  if (executed && !uncacheable && !describe)
400
397
    return(false);
401
398
  executed= 1;
402
 
  
 
399
 
403
400
  if (uncacheable || !item || !item->assigned() || describe)
404
401
  {
405
402
    if (item)
418
415
        assert(0);
419
416
      }
420
417
    }
421
 
    for (SELECT_LEX *sl= select_cursor; sl; sl= sl->next_select())
 
418
    for (Select_Lex *sl= select_cursor; sl; sl= sl->next_select())
422
419
    {
423
420
      ha_rows records_at_start= 0;
424
 
      thd->lex->current_select= sl;
 
421
      session->lex->current_select= sl;
425
422
 
426
423
      if (optimized)
427
424
        saved_error= sl->join->reinit();
444
441
          we don't calculate found_rows() per union part.
445
442
          Otherwise, SQL_CALC_FOUND_ROWS should be done on all sub parts.
446
443
        */
447
 
        sl->join->select_options= 
 
444
        sl->join->select_options=
448
445
          (select_limit_cnt == HA_POS_ERROR || sl->braces) ?
449
446
          sl->options & ~OPTION_FOUND_ROWS : sl->options | found_rows_for_union;
450
447
 
451
 
        /* dump_TableList_struct(select_lex, select_lex->leaf_tables); */
452
448
        if (sl->join->flatten_subqueries())
453
449
          return(true);
454
450
 
455
 
        /* dump_TableList_struct(select_lex, select_lex->leaf_tables); */
456
451
        saved_error= sl->join->optimize();
457
452
      }
458
453
      if (!saved_error)
471
466
                                    0);
472
467
        if (!saved_error)
473
468
        {
474
 
          examined_rows+= thd->examined_row_count;
 
469
          examined_rows+= session->examined_row_count;
475
470
          if (union_result->flush())
476
471
          {
477
 
            thd->lex->current_select= lex_select_save;
 
472
            session->lex->current_select= lex_select_save;
478
473
            return(1);
479
474
          }
480
475
        }
481
476
      }
482
477
      if (saved_error)
483
478
      {
484
 
        thd->lex->current_select= lex_select_save;
 
479
        session->lex->current_select= lex_select_save;
485
480
        return(saved_error);
486
481
      }
487
482
      /* Needed for the following test and for records_at_start in next loop */
491
486
        table->file->print_error(error, MYF(0));
492
487
        return(1);
493
488
      }
494
 
      if (found_rows_for_union && !sl->braces && 
 
489
      if (found_rows_for_union && !sl->braces &&
495
490
          select_limit_cnt != HA_POS_ERROR)
496
491
      {
497
492
        /*
500
495
          We get this from the difference of between total number of possible
501
496
          rows and actual rows added to the temporary table.
502
497
        */
503
 
        add_rows+= (uint64_t) (thd->limit_found_rows - (uint64_t)
 
498
        add_rows+= (uint64_t) (session->limit_found_rows - (uint64_t)
504
499
                              ((table->file->stats.records -  records_at_start)));
505
500
      }
506
501
    }
510
505
  /* Send result to 'result' */
511
506
  saved_error= true;
512
507
  {
513
 
    if (!thd->is_fatal_error)                           // Check if EOM
 
508
    if (!session->is_fatal_error)                               // Check if EOM
514
509
    {
515
510
      set_limit(global_parameters);
516
 
      init_prepare_fake_select_lex(thd);
 
511
      init_prepare_fake_select_lex(session);
517
512
      JOIN *join= fake_select_lex->join;
518
513
      if (!join)
519
514
      {
525
520
          don't let it allocate the join. Perhaps this is because we need
526
521
          some special parameter values passed to join constructor?
527
522
        */
528
 
        if (!(fake_select_lex->join= new JOIN(thd, item_list,
 
523
        if (!(fake_select_lex->join= new JOIN(session, item_list,
529
524
                                              fake_select_lex->options, result)))
530
525
        {
531
526
          fake_select_lex->table_list.empty();
534
529
        fake_select_lex->join->no_const_tables= true;
535
530
 
536
531
        /*
537
 
          Fake st_select_lex should have item list for correctref_array
 
532
          Fake Select_Lex should have item list for correctref_array
538
533
          allocation.
539
534
        */
540
535
        fake_select_lex->item_list= item_list;
541
 
        saved_error= mysql_select(thd, &fake_select_lex->ref_pointer_array,
 
536
        saved_error= mysql_select(session, &fake_select_lex->ref_pointer_array,
542
537
                              &result_table_list,
543
538
                              0, item_list, NULL,
544
539
                              global_parameters->order_list.elements,
545
540
                              (order_st*)global_parameters->order_list.first,
546
 
                              (order_st*) NULL, NULL, (order_st*) NULL,
 
541
                              (order_st*) NULL, NULL,
547
542
                              fake_select_lex->options | SELECT_NO_UNLOCK,
548
543
                              result, this, fake_select_lex);
549
544
      }
557
552
             - 1st time is a real evaluation to get the subquery value
558
553
             - 2nd time is to produce EXPLAIN output rows.
559
554
            1st execution sets certain members (e.g. select_result) to perform
560
 
            subquery execution rather than EXPLAIN line production. In order 
 
555
            subquery execution rather than EXPLAIN line production. In order
561
556
            to reset them back, we re-do all of the actions (yes it is ugly):
562
557
          */
563
 
          join->init(thd, item_list, fake_select_lex->options, result);
564
 
          saved_error= mysql_select(thd, &fake_select_lex->ref_pointer_array,
 
558
          join->init(session, item_list, fake_select_lex->options, result);
 
559
          saved_error= mysql_select(session, &fake_select_lex->ref_pointer_array,
565
560
                                &result_table_list,
566
561
                                0, item_list, NULL,
567
562
                                global_parameters->order_list.elements,
568
563
                                (order_st*)global_parameters->order_list.first,
569
 
                                (order_st*) NULL, NULL, (order_st*) NULL,
 
564
                                (order_st*) NULL, NULL,
570
565
                                fake_select_lex->options | SELECT_NO_UNLOCK,
571
566
                                result, this, fake_select_lex);
572
567
        }
581
576
      fake_select_lex->table_list.empty();
582
577
      if (!saved_error)
583
578
      {
584
 
        thd->limit_found_rows = (uint64_t)table->file->stats.records + add_rows;
585
 
        thd->examined_row_count+= examined_rows;
 
579
        session->limit_found_rows = (uint64_t)table->file->stats.records + add_rows;
 
580
        session->examined_row_count+= examined_rows;
586
581
      }
587
582
      /*
588
583
        Mark for slow query log if any of the union parts didn't use
590
585
      */
591
586
    }
592
587
  }
593
 
  thd->lex->current_select= lex_select_save;
 
588
  session->lex->current_select= lex_select_save;
594
589
  return(saved_error);
595
590
}
596
591
 
597
592
 
598
 
bool st_select_lex_unit::cleanup()
 
593
bool Select_Lex_Unit::cleanup()
599
594
{
600
595
  int error= 0;
601
596
 
610
605
    delete union_result;
611
606
    union_result=0; // Safety
612
607
    if (table)
613
 
      table->free_tmp_table(thd);
 
608
      table->free_tmp_table(session);
614
609
    table= 0; // Safety
615
610
  }
616
611
 
617
 
  for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select())
 
612
  for (Select_Lex *sl= first_select(); sl; sl= sl->next_select())
618
613
    error|= sl->cleanup();
619
614
 
620
615
  if (fake_select_lex)
638
633
}
639
634
 
640
635
 
641
 
void st_select_lex_unit::reinit_exec_mechanism()
 
636
void Select_Lex_Unit::reinit_exec_mechanism()
642
637
{
643
638
  prepared= optimized= executed= 0;
644
639
}
648
643
  change select_result object of unit
649
644
 
650
645
  SYNOPSIS
651
 
    st_select_lex_unit::change_result()
 
646
    Select_Lex_Unit::change_result()
652
647
    result      new select_result object
653
648
    old_result  old select_result object
654
649
 
657
652
    true  - error
658
653
*/
659
654
 
660
 
bool st_select_lex_unit::change_result(select_result_interceptor *new_result,
 
655
bool Select_Lex_Unit::change_result(select_result_interceptor *new_result,
661
656
                                       select_result_interceptor *old_result)
662
657
{
663
658
  bool res= false;
664
 
  for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select())
 
659
  for (Select_Lex *sl= first_select(); sl; sl= sl->next_select())
665
660
  {
666
661
    if (sl->join && sl->join->result == old_result)
667
662
      if (sl->join->change_result(new_result))
676
671
  Get column type information for this unit.
677
672
 
678
673
  SYNOPSIS
679
 
    st_select_lex_unit::get_unit_column_types()
 
674
    Select_Lex_Unit::get_unit_column_types()
680
675
 
681
676
  DESCRIPTION
682
677
    For a single-select the column types are taken
683
678
    from the list of selected items. For a union this function
684
 
    assumes that st_select_lex_unit::prepare has been called
 
679
    assumes that Select_Lex_Unit::prepare has been called
685
680
    and returns the type holders that were created for unioned
686
681
    column types of all selects.
687
682
 
688
683
  NOTES
689
684
    The implementation of this function should be in sync with
690
 
    st_select_lex_unit::prepare()
 
685
    Select_Lex_Unit::prepare()
691
686
*/
692
687
 
693
 
List<Item> *st_select_lex_unit::get_unit_column_types()
 
688
List<Item> *Select_Lex_Unit::get_unit_column_types()
694
689
{
695
 
  SELECT_LEX *sl= first_select();
 
690
  Select_Lex *sl= first_select();
696
691
 
697
692
  if (is_union())
698
693
  {
704
699
  return &sl->item_list;
705
700
}
706
701
 
707
 
bool st_select_lex::cleanup()
 
702
bool Select_Lex::cleanup()
708
703
{
709
704
  bool error= false;
710
705
 
711
706
  if (join)
712
707
  {
713
 
    assert((st_select_lex*)join->select_lex == this);
 
708
    assert((Select_Lex*)join->select_lex == this);
714
709
    error= join->destroy();
715
710
    delete join;
716
711
    join= 0;
717
712
  }
718
 
  for (SELECT_LEX_UNIT *lex_unit= first_inner_unit(); lex_unit ;
 
713
  for (Select_Lex_Unit *lex_unit= first_inner_unit(); lex_unit ;
719
714
       lex_unit= lex_unit->next_unit())
720
715
  {
721
 
    error= (bool) ((uint) error | (uint) lex_unit->cleanup());
 
716
    error= (bool) ((uint32_t) error | (uint32_t) lex_unit->cleanup());
722
717
  }
723
718
  non_agg_fields.empty();
724
719
  inner_refs_list.empty();
726
721
}
727
722
 
728
723
 
729
 
void st_select_lex::cleanup_all_joins(bool full)
 
724
void Select_Lex::cleanup_all_joins(bool full)
730
725
{
731
 
  SELECT_LEX_UNIT *unit;
732
 
  SELECT_LEX *sl;
 
726
  Select_Lex_Unit *unit;
 
727
  Select_Lex *sl;
733
728
 
734
729
  if (join)
735
730
    join->cleanup(full);