~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_union.cc

  • Committer: Eric Day
  • Date: 2009-08-27 07:26:22 UTC
  • mto: This revision was merged to the branch mainline in revision 1131.
  • Revision ID: eday@oddments.org-20090827072622-72te13ua0wdlc2ky
Reworked listen interface to not require binding of TCP ports.

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