~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_union.cc

  • Committer: Monty Taylor
  • Date: 2008-11-16 20:15:33 UTC
  • mto: (584.1.9 devel)
  • mto: This revision was merged to the branch mainline in revision 589.
  • Revision ID: monty@inaugust.com-20081116201533-d0f19s1bk1h95iyw
Removed a big bank of includes from item.h.

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