~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_union.cc

  • Committer: Brian Aker
  • Date: 2009-01-24 09:43:35 UTC
  • Revision ID: brian@gir-3.local-20090124094335-6qdtvc35gl5fvivz
Adding in an example singe thread scheduler

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
  UNION  of select's
18
18
  UNION's  were introduced by Monty and Sinisa <sinisa@mysql.com>
19
19
*/
20
 
#include "config.h"
 
20
#include <drizzled/server_includes.h>
21
21
#include <drizzled/sql_select.h>
22
22
#include <drizzled/error.h>
23
23
#include <drizzled/item/type_holder.h>
24
24
#include <drizzled/sql_base.h>
25
 
#include <drizzled/sql_union.h>
26
 
 
27
 
namespace drizzled
28
 
{
29
 
 
30
 
bool drizzle_union(Session *session, LEX *, select_result *result,
31
 
                   Select_Lex_Unit *unit, uint64_t setup_tables_done_option)
 
25
 
 
26
bool mysql_union(Session *session, LEX *, select_result *result,
 
27
                 SELECT_LEX_UNIT *unit, ulong setup_tables_done_option)
32
28
{
33
29
  bool res;
34
30
  if (!(res= unit->prepare(session, result, SELECT_NO_UNLOCK |
44
40
** store records in temporary table for UNION
45
41
***************************************************************************/
46
42
 
47
 
int select_union::prepare(List<Item> &, Select_Lex_Unit *u)
 
43
int select_union::prepare(List<Item> &, SELECT_LEX_UNIT *u)
48
44
{
49
45
  unit= u;
50
46
  return 0;
59
55
    unit->offset_limit_cnt--;
60
56
    return 0;
61
57
  }
62
 
  fill_record(session, table->field, values, true);
 
58
  fill_record(session, table->field, values, 1);
63
59
  if (session->is_error())
64
60
    return 1;
65
61
 
66
 
  if ((error= table->cursor->ha_write_row(table->record[0])))
 
62
  if ((error= table->file->ha_write_row(table->record[0])))
67
63
  {
68
64
    /* create_myisam_from_heap will generate error if needed */
69
 
    if (table->cursor->is_fatal_error(error, HA_CHECK_DUP) &&
 
65
    if (table->file->is_fatal_error(error, HA_CHECK_DUP) &&
70
66
        create_myisam_from_heap(session, table, tmp_table_param.start_recinfo,
71
67
                                &tmp_table_param.recinfo, error, 1))
72
68
      return 1;
84
80
bool select_union::flush()
85
81
{
86
82
  int error;
87
 
  if ((error=table->cursor->extra(HA_EXTRA_NO_CACHE)))
 
83
  if ((error=table->file->extra(HA_EXTRA_NO_CACHE)))
88
84
  {
89
 
    table->print_error(error, MYF(0));
 
85
    table->file->print_error(error, MYF(0));
90
86
    return 1;
91
87
  }
92
88
  return 0;
104
100
                         duplicates on insert
105
101
      options            create options
106
102
      table_alias        name of the temporary table
 
103
      bit_fields_as_long convert bit fields to uint64_t
107
104
 
108
105
  DESCRIPTION
109
106
    Create a temporary table that is used to store the result of a UNION,
117
114
bool
118
115
select_union::create_result_table(Session *session_arg, List<Item> *column_types,
119
116
                                  bool is_union_distinct, uint64_t options,
120
 
                                  const char *table_alias)
 
117
                                  const char *table_alias,
 
118
                                  bool bit_fields_as_long)
121
119
{
122
 
  assert(table == NULL);
 
120
  assert(table == 0);
123
121
  tmp_table_param.init();
124
122
  tmp_table_param.field_count= column_types->elements;
 
123
  tmp_table_param.bit_fields_as_long= bit_fields_as_long;
125
124
 
126
125
  if (! (table= create_tmp_table(session_arg, &tmp_table_param, *column_types,
127
 
                                 (order_st*) NULL, is_union_distinct, 1,
 
126
                                 (order_st*) 0, is_union_distinct, 1,
128
127
                                 options, HA_POS_ERROR, (char*) table_alias)))
129
128
    return true;
130
 
  table->cursor->extra(HA_EXTRA_WRITE_CACHE);
131
 
  table->cursor->extra(HA_EXTRA_IGNORE_DUP_KEY);
 
129
  table->file->extra(HA_EXTRA_WRITE_CACHE);
 
130
  table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
132
131
  return false;
133
132
}
134
133
 
142
141
 
143
142
void select_union::cleanup()
144
143
{
145
 
  table->cursor->extra(HA_EXTRA_RESET_STATE);
146
 
  table->cursor->ha_delete_all_rows();
147
 
  table->free_io_cache();
148
 
  table->filesort_free_buffers();
 
144
  table->file->extra(HA_EXTRA_RESET_STATE);
 
145
  table->file->ha_delete_all_rows();
 
146
  free_io_cache(table);
 
147
  filesort_free_buffers(table,0);
149
148
}
150
149
 
151
150
 
153
152
  initialization procedures before fake_select_lex preparation()
154
153
 
155
154
  SYNOPSIS
156
 
    Select_Lex_Unit::init_prepare_fake_select_lex()
 
155
    st_select_lex_unit::init_prepare_fake_select_lex()
157
156
    session             - thread handler
158
157
 
159
158
  RETURN
161
160
*/
162
161
 
163
162
void
164
 
Select_Lex_Unit::init_prepare_fake_select_lex(Session *session_arg)
 
163
st_select_lex_unit::init_prepare_fake_select_lex(Session *session_arg)
165
164
{
166
165
  session_arg->lex->current_select= fake_select_lex;
167
166
  fake_select_lex->table_list.link_in_list((unsigned char *)&result_table_list,
186
185
}
187
186
 
188
187
 
189
 
bool Select_Lex_Unit::prepare(Session *session_arg, select_result *sel_result,
190
 
                              uint64_t additional_options)
 
188
bool st_select_lex_unit::prepare(Session *session_arg, select_result *sel_result,
 
189
                                 uint32_t additional_options)
191
190
{
192
 
  Select_Lex *lex_select_save= session_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;
273
272
                                sl->order_list.elements) +
274
273
                               sl->group_list.elements,
275
274
                               can_skip_order_by ?
276
 
                               (order_st*) NULL : (order_st *)sl->order_list.first,
 
275
                               (order_st*) 0 : (order_st *)sl->order_list.first,
277
276
                               (order_st*) sl->group_list.first,
278
277
                               sl->having,
 
278
                               (is_union_select ? (order_st*) 0 :
 
279
                                (order_st*) session_arg->lex->proc_list.first),
279
280
                               sl, this);
280
281
    /* There are no * in the statement anymore (for PS) */
281
282
    sl->with_wild= 0;
353
354
                     TMP_TABLE_ALL_COLUMNS);
354
355
 
355
356
    if (union_result->create_result_table(session, &types, test(union_distinct),
356
 
                                          create_options, ""))
 
357
                                          create_options, "", false))
357
358
      goto err;
358
359
    memset(&result_table_list, 0, sizeof(result_table_list));
359
360
    result_table_list.db= (char*) "";
360
 
    result_table_list.alias= "union";
361
 
    result_table_list.table_name= (char *) "union";
 
361
    result_table_list.table_name= result_table_list.alias= (char*) "union";
362
362
    result_table_list.table= table= union_result->table;
363
363
 
364
364
    session_arg->lex->current_select= lex_select_save;
388
388
}
389
389
 
390
390
 
391
 
bool Select_Lex_Unit::exec()
 
391
bool st_select_lex_unit::exec()
392
392
{
393
 
  Select_Lex *lex_select_save= session->lex->current_select;
394
 
  Select_Lex *select_cursor=first_select();
 
393
  SELECT_LEX *lex_select_save= session->lex->current_select;
 
394
  SELECT_LEX *select_cursor=first_select();
395
395
  uint64_t add_rows=0;
396
396
  ha_rows examined_rows= 0;
397
397
 
409
409
      {
410
410
        item->assigned(0); // We will reinit & rexecute unit
411
411
        item->reset();
412
 
        table->cursor->ha_delete_all_rows();
 
412
        table->file->ha_delete_all_rows();
413
413
      }
414
414
      /* re-enabling indexes for next subselect iteration */
415
 
      if (union_distinct && table->cursor->ha_enable_indexes(HA_KEY_SWITCH_ALL))
 
415
      if (union_distinct && table->file->ha_enable_indexes(HA_KEY_SWITCH_ALL))
416
416
      {
417
417
        assert(0);
418
418
      }
419
419
    }
420
 
    for (Select_Lex *sl= select_cursor; sl; sl= sl->next_select())
 
420
    for (SELECT_LEX *sl= select_cursor; sl; sl= sl->next_select())
421
421
    {
422
422
      ha_rows records_at_start= 0;
423
423
      session->lex->current_select= sl;
431
431
        {
432
432
          offset_limit_cnt= 0;
433
433
          /*
434
 
            We can't use LIMIT at this stage if we are using ORDER BY for the
 
434
            We can't use LIMIT at this stage if we are using order_st BY for the
435
435
            whole query
436
436
          */
437
437
          if (sl->order_list.first || describe)
447
447
          (select_limit_cnt == HA_POS_ERROR || sl->braces) ?
448
448
          sl->options & ~OPTION_FOUND_ROWS : sl->options | found_rows_for_union;
449
449
 
 
450
        if (sl->join->flatten_subqueries())
 
451
          return(true);
 
452
 
450
453
        saved_error= sl->join->optimize();
451
454
      }
452
455
      if (!saved_error)
453
456
      {
454
 
        records_at_start= table->cursor->stats.records;
 
457
        records_at_start= table->file->stats.records;
455
458
        sl->join->exec();
456
459
        if (sl == union_distinct)
457
460
        {
458
 
          if (table->cursor->ha_disable_indexes(HA_KEY_SWITCH_ALL))
 
461
          if (table->file->ha_disable_indexes(HA_KEY_SWITCH_ALL))
459
462
            return(true);
460
463
          table->no_keyread=1;
461
464
        }
479
482
        return(saved_error);
480
483
      }
481
484
      /* Needed for the following test and for records_at_start in next loop */
482
 
      int error= table->cursor->info(HA_STATUS_VARIABLE);
483
 
      if (error)
 
485
      int error= table->file->info(HA_STATUS_VARIABLE);
 
486
      if(error)
484
487
      {
485
 
        table->print_error(error, MYF(0));
 
488
        table->file->print_error(error, MYF(0));
486
489
        return(1);
487
490
      }
488
491
      if (found_rows_for_union && !sl->braces &&
495
498
          rows and actual rows added to the temporary table.
496
499
        */
497
500
        add_rows+= (uint64_t) (session->limit_found_rows - (uint64_t)
498
 
                              ((table->cursor->stats.records -  records_at_start)));
 
501
                              ((table->file->stats.records -  records_at_start)));
499
502
      }
500
503
    }
501
504
  }
528
531
        fake_select_lex->join->no_const_tables= true;
529
532
 
530
533
        /*
531
 
          Fake Select_Lex should have item list for correctref_array
 
534
          Fake st_select_lex should have item list for correctref_array
532
535
          allocation.
533
536
        */
534
537
        fake_select_lex->item_list= item_list;
537
540
                              0, item_list, NULL,
538
541
                              global_parameters->order_list.elements,
539
542
                              (order_st*)global_parameters->order_list.first,
540
 
                              (order_st*) NULL, NULL,
 
543
                              (order_st*) NULL, NULL, (order_st*) NULL,
541
544
                              fake_select_lex->options | SELECT_NO_UNLOCK,
542
545
                              result, this, fake_select_lex);
543
546
      }
554
557
            subquery execution rather than EXPLAIN line production. In order
555
558
            to reset them back, we re-do all of the actions (yes it is ugly):
556
559
          */
557
 
                join->reset(session, item_list, fake_select_lex->options, result);
 
560
          join->init(session, item_list, fake_select_lex->options, result);
558
561
          saved_error= mysql_select(session, &fake_select_lex->ref_pointer_array,
559
562
                                &result_table_list,
560
563
                                0, item_list, NULL,
561
564
                                global_parameters->order_list.elements,
562
565
                                (order_st*)global_parameters->order_list.first,
563
 
                                (order_st*) NULL, NULL,
 
566
                                (order_st*) NULL, NULL, (order_st*) NULL,
564
567
                                fake_select_lex->options | SELECT_NO_UNLOCK,
565
568
                                result, this, fake_select_lex);
566
569
        }
575
578
      fake_select_lex->table_list.empty();
576
579
      if (!saved_error)
577
580
      {
578
 
        session->limit_found_rows = (uint64_t)table->cursor->stats.records + add_rows;
 
581
        session->limit_found_rows = (uint64_t)table->file->stats.records + add_rows;
579
582
        session->examined_row_count+= examined_rows;
580
583
      }
581
584
      /*
589
592
}
590
593
 
591
594
 
592
 
bool Select_Lex_Unit::cleanup()
 
595
bool st_select_lex_unit::cleanup()
593
596
{
594
597
  int error= 0;
595
598
 
608
611
    table= 0; // Safety
609
612
  }
610
613
 
611
 
  for (Select_Lex *sl= first_select(); sl; sl= sl->next_select())
 
614
  for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select())
612
615
    error|= sl->cleanup();
613
616
 
614
617
  if (fake_select_lex)
632
635
}
633
636
 
634
637
 
635
 
void Select_Lex_Unit::reinit_exec_mechanism()
 
638
void st_select_lex_unit::reinit_exec_mechanism()
636
639
{
637
640
  prepared= optimized= executed= 0;
638
641
}
642
645
  change select_result object of unit
643
646
 
644
647
  SYNOPSIS
645
 
    Select_Lex_Unit::change_result()
 
648
    st_select_lex_unit::change_result()
646
649
    result      new select_result object
647
650
    old_result  old select_result object
648
651
 
651
654
    true  - error
652
655
*/
653
656
 
654
 
bool Select_Lex_Unit::change_result(select_result_interceptor *new_result,
 
657
bool st_select_lex_unit::change_result(select_result_interceptor *new_result,
655
658
                                       select_result_interceptor *old_result)
656
659
{
657
660
  bool res= false;
658
 
  for (Select_Lex *sl= first_select(); sl; sl= sl->next_select())
 
661
  for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select())
659
662
  {
660
663
    if (sl->join && sl->join->result == old_result)
661
664
      if (sl->join->change_result(new_result))
670
673
  Get column type information for this unit.
671
674
 
672
675
  SYNOPSIS
673
 
    Select_Lex_Unit::get_unit_column_types()
 
676
    st_select_lex_unit::get_unit_column_types()
674
677
 
675
678
  DESCRIPTION
676
679
    For a single-select the column types are taken
677
680
    from the list of selected items. For a union this function
678
 
    assumes that Select_Lex_Unit::prepare has been called
 
681
    assumes that st_select_lex_unit::prepare has been called
679
682
    and returns the type holders that were created for unioned
680
683
    column types of all selects.
681
684
 
682
685
  NOTES
683
686
    The implementation of this function should be in sync with
684
 
    Select_Lex_Unit::prepare()
 
687
    st_select_lex_unit::prepare()
685
688
*/
686
689
 
687
 
List<Item> *Select_Lex_Unit::get_unit_column_types()
 
690
List<Item> *st_select_lex_unit::get_unit_column_types()
688
691
{
689
 
  Select_Lex *sl= first_select();
 
692
  SELECT_LEX *sl= first_select();
690
693
 
691
694
  if (is_union())
692
695
  {
698
701
  return &sl->item_list;
699
702
}
700
703
 
701
 
bool Select_Lex::cleanup()
 
704
bool st_select_lex::cleanup()
702
705
{
703
706
  bool error= false;
704
707
 
705
708
  if (join)
706
709
  {
707
 
    assert((Select_Lex*)join->select_lex == this);
 
710
    assert((st_select_lex*)join->select_lex == this);
708
711
    error= join->destroy();
709
712
    delete join;
710
713
    join= 0;
711
714
  }
712
 
  for (Select_Lex_Unit *lex_unit= first_inner_unit(); lex_unit ;
 
715
  for (SELECT_LEX_UNIT *lex_unit= first_inner_unit(); lex_unit ;
713
716
       lex_unit= lex_unit->next_unit())
714
717
  {
715
 
    error= (bool) ((uint32_t) error | (uint32_t) lex_unit->cleanup());
 
718
    error= (bool) ((uint) error | (uint) lex_unit->cleanup());
716
719
  }
717
720
  non_agg_fields.empty();
718
721
  inner_refs_list.empty();
720
723
}
721
724
 
722
725
 
723
 
void Select_Lex::cleanup_all_joins(bool full)
 
726
void st_select_lex::cleanup_all_joins(bool full)
724
727
{
725
 
  Select_Lex_Unit *unit;
726
 
  Select_Lex *sl;
 
728
  SELECT_LEX_UNIT *unit;
 
729
  SELECT_LEX *sl;
727
730
 
728
731
  if (join)
729
732
    join->cleanup(full);
732
735
    for (sl= unit->first_select(); sl; sl= sl->next_select())
733
736
      sl->cleanup_all_joins(full);
734
737
}
735
 
 
736
 
} /* namespace drizzled */