~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to sql/sql_union.cc

Removed SCCS references.

Show diffs side-by-side

added added

removed removed

Lines of Context:
13
13
   along with this program; if not, write to the Free Software
14
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
15
 
 
16
 
16
17
/*
17
18
  UNION  of select's
18
19
  UNION's  were introduced by Monty and Sinisa <sinisa@mysql.com>
19
20
*/
20
 
#include <drizzled/server_includes.h>
21
 
#include <drizzled/sql_select.h>
22
 
#include <drizzled/drizzled_error_messages.h>
23
 
 
24
 
bool mysql_union(THD *thd,
25
 
                 LEX *lex __attribute__((unused)),
26
 
                 select_result *result,
 
21
 
 
22
 
 
23
#include "mysql_priv.h"
 
24
#include "sql_select.h"
 
25
 
 
26
bool mysql_union(THD *thd, LEX *lex, select_result *result,
27
27
                 SELECT_LEX_UNIT *unit, ulong setup_tables_done_option)
28
28
{
 
29
  DBUG_ENTER("mysql_union");
29
30
  bool res;
30
31
  if (!(res= unit->prepare(thd, result, SELECT_NO_UNLOCK |
31
32
                           setup_tables_done_option)))
32
33
    res= unit->exec();
33
34
  if (res)
34
35
    res|= unit->cleanup();
35
 
  return(res);
 
36
  DBUG_RETURN(res);
36
37
}
37
38
 
38
39
 
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> &list, SELECT_LEX_UNIT *u)
45
45
{
46
46
  unit= u;
47
47
  return 0;
101
101
                         duplicates on insert
102
102
      options            create options
103
103
      table_alias        name of the temporary table
104
 
      bit_fields_as_long convert bit fields to uint64_t
 
104
      bit_fields_as_long convert bit fields to ulonglong
105
105
 
106
106
  DESCRIPTION
107
107
    Create a temporary table that is used to store the result of a UNION,
114
114
 
115
115
bool
116
116
select_union::create_result_table(THD *thd_arg, List<Item> *column_types,
117
 
                                  bool is_union_distinct, uint64_t options,
 
117
                                  bool is_union_distinct, ulonglong options,
118
118
                                  const char *table_alias,
119
119
                                  bool bit_fields_as_long)
120
120
{
121
 
  assert(table == 0);
 
121
  DBUG_ASSERT(table == 0);
122
122
  tmp_table_param.init();
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
126
  if (! (table= create_tmp_table(thd_arg, &tmp_table_param, *column_types,
127
 
                                 (order_st*) 0, is_union_distinct, 1,
 
127
                                 (ORDER*) 0, is_union_distinct, 1,
128
128
                                 options, HA_POS_ERROR, (char*) table_alias)))
129
 
    return true;
 
129
    return TRUE;
130
130
  table->file->extra(HA_EXTRA_WRITE_CACHE);
131
131
  table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
132
 
  return false;
 
132
  return FALSE;
133
133
}
134
134
 
135
135
 
164
164
st_select_lex_unit::init_prepare_fake_select_lex(THD *thd_arg) 
165
165
{
166
166
  thd_arg->lex->current_select= fake_select_lex;
167
 
  fake_select_lex->table_list.link_in_list((unsigned char *)&result_table_list,
168
 
                                           (unsigned char **)
 
167
  fake_select_lex->table_list.link_in_list((uchar *)&result_table_list,
 
168
                                           (uchar **)
169
169
                                           &result_table_list.next_local);
170
170
  fake_select_lex->context.table_list= 
171
171
    fake_select_lex->context.first_name_resolution_table= 
172
172
    fake_select_lex->get_table_list();
173
 
 
174
 
  for (order_st *order= (order_st *) global_parameters->order_list.first;
175
 
       order;
176
 
       order= order->next)
177
 
    order->item= &order->item_ptr;
178
 
 
179
 
  for (order_st *order= (order_st *)global_parameters->order_list.first;
 
173
  if (!fake_select_lex->first_execution)
 
174
  {
 
175
    for (ORDER *order= (ORDER *) global_parameters->order_list.first;
 
176
         order;
 
177
         order= order->next)
 
178
      order->item= &order->item_ptr;
 
179
  }
 
180
  for (ORDER *order= (ORDER *)global_parameters->order_list.first;
180
181
       order;
181
182
       order=order->next)
182
183
  {
183
184
    (*order->item)->walk(&Item::change_context_processor, 0,
184
 
                         (unsigned char*) &fake_select_lex->context);
 
185
                         (uchar*) &fake_select_lex->context);
185
186
  }
186
187
}
187
188
 
188
189
 
189
190
bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
190
 
                                 uint32_t additional_options)
 
191
                                 ulong additional_options)
191
192
{
192
193
  SELECT_LEX *lex_select_save= thd_arg->lex->current_select;
193
194
  SELECT_LEX *sl, *first_sl= first_select();
194
195
  select_result *tmp_result;
195
196
  bool is_union_select;
196
 
  Table *empty_table= 0;
 
197
  TABLE *empty_table= 0;
 
198
  DBUG_ENTER("st_select_lex_unit::prepare");
197
199
 
198
200
  describe= test(additional_options & SELECT_DESCRIBE);
199
201
 
215
217
        offset_limit_cnt= 0;
216
218
        if (result->prepare(sl->join->fields_list, this))
217
219
        {
218
 
          return(true);
 
220
          DBUG_RETURN(TRUE);
219
221
        }
220
222
        sl->join->select_options|= SELECT_DESCRIBE;
221
223
        sl->join->reinit();
222
224
      }
223
225
    }
224
 
    return(false);
 
226
    DBUG_RETURN(FALSE);
225
227
  }
226
228
  prepared= 1;
227
 
  saved_error= false;
 
229
  saved_error= FALSE;
228
230
  
229
231
  thd_arg->lex->current_select= sl= first_sl;
230
232
  found_rows_for_union= first_sl->options & OPTION_FOUND_ROWS;
242
244
  else
243
245
    tmp_result= sel_result;
244
246
 
245
 
  sl->context.resolve_in_select_list= true;
 
247
  sl->context.resolve_in_select_list= TRUE;
246
248
 
247
249
  for (;sl; sl= sl->next_select())
248
250
  {
266
268
    can_skip_order_by= is_union_select && !(sl->braces && sl->explicit_limit);
267
269
 
268
270
    saved_error= join->prepare(&sl->ref_pointer_array,
269
 
                               (TableList*) sl->table_list.first,
 
271
                               (TABLE_LIST*) sl->table_list.first,
270
272
                               sl->with_wild,
271
273
                               sl->where,
272
274
                               (can_skip_order_by ? 0 :
273
275
                                sl->order_list.elements) +
274
276
                               sl->group_list.elements,
275
277
                               can_skip_order_by ?
276
 
                               (order_st*) 0 : (order_st *)sl->order_list.first,
277
 
                               (order_st*) sl->group_list.first,
 
278
                               (ORDER*) 0 : (ORDER *)sl->order_list.first,
 
279
                               (ORDER*) sl->group_list.first,
278
280
                               sl->having,
279
 
                               (is_union_select ? (order_st*) 0 :
280
 
                                (order_st*) thd_arg->lex->proc_list.first),
 
281
                               (is_union_select ? (ORDER*) 0 :
 
282
                                (ORDER*) thd_arg->lex->proc_list.first),
281
283
                               sl, this);
282
284
    /* There are no * in the statement anymore (for PS) */
283
285
    sl->with_wild= 0;
298
300
        The main reason of this is that we can't create
299
301
        field object without table.
300
302
      */
301
 
      assert(!empty_table);
302
 
      empty_table= (Table*) thd->calloc(sizeof(Table));
 
303
      DBUG_ASSERT(!empty_table);
 
304
      empty_table= (TABLE*) thd->calloc(sizeof(TABLE));
303
305
      types.empty();
304
306
      List_iterator_fast<Item> it(sl->item_list);
305
307
      Item *item_tmp;
326
328
      while ((type= tp++, item_tmp= it++))
327
329
      {
328
330
        if (((Item_type_holder*)type)->join_types(thd_arg, item_tmp))
329
 
          return(true);
 
331
          DBUG_RETURN(TRUE);
330
332
      }
331
333
    }
332
334
  }
339
341
    */
340
342
    List_iterator_fast<Item> tp(types);
341
343
    Item *type;
342
 
    uint64_t create_options;
 
344
    ulonglong create_options;
343
345
 
344
346
    while ((type= tp++))
345
347
    {
355
357
                     TMP_TABLE_ALL_COLUMNS);
356
358
 
357
359
    if (union_result->create_result_table(thd, &types, test(union_distinct),
358
 
                                          create_options, "", false))
 
360
                                          create_options, "", FALSE))
359
361
      goto err;
360
 
    memset(&result_table_list, 0, sizeof(result_table_list));
 
362
    bzero((char*) &result_table_list, sizeof(result_table_list));
361
363
    result_table_list.db= (char*) "";
362
364
    result_table_list.table_name= result_table_list.alias= (char*) "union";
363
365
    result_table_list.table= table= union_result->table;
371
373
    }
372
374
    else
373
375
    {
 
376
      DBUG_ASSERT(thd->stmt_arena->is_conventional() == false);
374
377
      /*
375
378
        We're in execution of a prepared statement or stored procedure:
376
379
        reset field items to point at fields from the created temporary table.
377
380
      */
378
 
      assert(1);
 
381
      table->reset_item_list(&item_list);
379
382
    }
380
383
  }
381
384
 
382
385
  thd_arg->lex->current_select= lex_select_save;
383
386
 
384
 
  return(saved_error || thd_arg->is_fatal_error);
 
387
  DBUG_RETURN(saved_error || thd_arg->is_fatal_error);
385
388
 
386
389
err:
387
390
  thd_arg->lex->current_select= lex_select_save;
388
 
  return(true);
 
391
  DBUG_RETURN(TRUE);
389
392
}
390
393
 
391
394
 
393
396
{
394
397
  SELECT_LEX *lex_select_save= thd->lex->current_select;
395
398
  SELECT_LEX *select_cursor=first_select();
396
 
  uint64_t add_rows=0;
 
399
  ulonglong add_rows=0;
397
400
  ha_rows examined_rows= 0;
 
401
  DBUG_ENTER("st_select_lex_unit::exec");
398
402
 
399
403
  if (executed && !uncacheable && !describe)
400
 
    return(false);
 
404
    DBUG_RETURN(FALSE);
401
405
  executed= 1;
402
406
  
403
407
  if (uncacheable || !item || !item->assigned() || describe)
415
419
      /* re-enabling indexes for next subselect iteration */
416
420
      if (union_distinct && table->file->ha_enable_indexes(HA_KEY_SWITCH_ALL))
417
421
      {
418
 
        assert(0);
 
422
        DBUG_ASSERT(0);
419
423
      }
420
424
    }
421
425
    for (SELECT_LEX *sl= select_cursor; sl; sl= sl->next_select())
432
436
        {
433
437
          offset_limit_cnt= 0;
434
438
          /*
435
 
            We can't use LIMIT at this stage if we are using order_st BY for the
 
439
            We can't use LIMIT at this stage if we are using ORDER BY for the
436
440
            whole query
437
441
          */
438
442
          if (sl->order_list.first || describe)
448
452
          (select_limit_cnt == HA_POS_ERROR || sl->braces) ?
449
453
          sl->options & ~OPTION_FOUND_ROWS : sl->options | found_rows_for_union;
450
454
 
451
 
        /* dump_TableList_struct(select_lex, select_lex->leaf_tables); */
 
455
        /* dump_TABLE_LIST_struct(select_lex, select_lex->leaf_tables); */
452
456
        if (sl->join->flatten_subqueries())
453
 
          return(true);
 
457
          DBUG_RETURN(TRUE);
454
458
 
455
 
        /* dump_TableList_struct(select_lex, select_lex->leaf_tables); */
 
459
        /* dump_TABLE_LIST_struct(select_lex, select_lex->leaf_tables); */
456
460
        saved_error= sl->join->optimize();
457
461
      }
458
462
      if (!saved_error)
462
466
        if (sl == union_distinct)
463
467
        {
464
468
          if (table->file->ha_disable_indexes(HA_KEY_SWITCH_ALL))
465
 
            return(true);
 
469
            DBUG_RETURN(TRUE);
466
470
          table->no_keyread=1;
467
471
        }
468
472
        saved_error= sl->join->error;
475
479
          if (union_result->flush())
476
480
          {
477
481
            thd->lex->current_select= lex_select_save;
478
 
            return(1);
 
482
            DBUG_RETURN(1);
479
483
          }
480
484
        }
481
485
      }
482
486
      if (saved_error)
483
487
      {
484
488
        thd->lex->current_select= lex_select_save;
485
 
        return(saved_error);
 
489
        DBUG_RETURN(saved_error);
486
490
      }
487
491
      /* Needed for the following test and for records_at_start in next loop */
488
492
      int error= table->file->info(HA_STATUS_VARIABLE);
489
493
      if(error)
490
494
      {
491
495
        table->file->print_error(error, MYF(0));
492
 
        return(1);
 
496
        DBUG_RETURN(1);
493
497
      }
494
498
      if (found_rows_for_union && !sl->braces && 
495
499
          select_limit_cnt != HA_POS_ERROR)
500
504
          We get this from the difference of between total number of possible
501
505
          rows and actual rows added to the temporary table.
502
506
        */
503
 
        add_rows+= (uint64_t) (thd->limit_found_rows - (uint64_t)
 
507
        add_rows+= (ulonglong) (thd->limit_found_rows - (ulonglong)
504
508
                              ((table->file->stats.records -  records_at_start)));
505
509
      }
506
510
    }
508
512
  optimized= 1;
509
513
 
510
514
  /* Send result to 'result' */
511
 
  saved_error= true;
 
515
  saved_error= TRUE;
512
516
  {
513
517
    if (!thd->is_fatal_error)                           // Check if EOM
514
518
    {
529
533
                                              fake_select_lex->options, result)))
530
534
        {
531
535
          fake_select_lex->table_list.empty();
532
 
          return(true);
 
536
          DBUG_RETURN(TRUE);
533
537
        }
534
 
        fake_select_lex->join->no_const_tables= true;
 
538
        fake_select_lex->join->no_const_tables= TRUE;
535
539
 
536
540
        /*
537
541
          Fake st_select_lex should have item list for correctref_array
542
546
                              &result_table_list,
543
547
                              0, item_list, NULL,
544
548
                              global_parameters->order_list.elements,
545
 
                              (order_st*)global_parameters->order_list.first,
546
 
                              (order_st*) NULL, NULL, (order_st*) NULL,
 
549
                              (ORDER*)global_parameters->order_list.first,
 
550
                              (ORDER*) NULL, NULL, (ORDER*) NULL,
547
551
                              fake_select_lex->options | SELECT_NO_UNLOCK,
548
552
                              result, this, fake_select_lex);
549
553
      }
565
569
                                &result_table_list,
566
570
                                0, item_list, NULL,
567
571
                                global_parameters->order_list.elements,
568
 
                                (order_st*)global_parameters->order_list.first,
569
 
                                (order_st*) NULL, NULL, (order_st*) NULL,
 
572
                                (ORDER*)global_parameters->order_list.first,
 
573
                                (ORDER*) NULL, NULL, (ORDER*) NULL,
570
574
                                fake_select_lex->options | SELECT_NO_UNLOCK,
571
575
                                result, this, fake_select_lex);
572
576
        }
581
585
      fake_select_lex->table_list.empty();
582
586
      if (!saved_error)
583
587
      {
584
 
        thd->limit_found_rows = (uint64_t)table->file->stats.records + add_rows;
 
588
        thd->limit_found_rows = (ulonglong)table->file->stats.records + add_rows;
585
589
        thd->examined_row_count+= examined_rows;
586
590
      }
587
591
      /*
591
595
    }
592
596
  }
593
597
  thd->lex->current_select= lex_select_save;
594
 
  return(saved_error);
 
598
  DBUG_RETURN(saved_error);
595
599
}
596
600
 
597
601
 
598
602
bool st_select_lex_unit::cleanup()
599
603
{
600
604
  int error= 0;
 
605
  DBUG_ENTER("st_select_lex_unit::cleanup");
601
606
 
602
607
  if (cleaned)
603
608
  {
604
 
    return(false);
 
609
    DBUG_RETURN(FALSE);
605
610
  }
606
611
  cleaned= 1;
607
612
 
610
615
    delete union_result;
611
616
    union_result=0; // Safety
612
617
    if (table)
613
 
      table->free_tmp_table(thd);
 
618
      free_tmp_table(thd, table);
614
619
    table= 0; // Safety
615
620
  }
616
621
 
628
633
    error|= fake_select_lex->cleanup();
629
634
    if (fake_select_lex->order_list.elements)
630
635
    {
631
 
      order_st *ord;
632
 
      for (ord= (order_st*)fake_select_lex->order_list.first; ord; ord= ord->next)
 
636
      ORDER *ord;
 
637
      for (ord= (ORDER*)fake_select_lex->order_list.first; ord; ord= ord->next)
633
638
        (*ord->item)->cleanup();
634
639
    }
635
640
  }
636
641
 
637
 
  return(error);
 
642
  DBUG_RETURN(error);
638
643
}
639
644
 
640
645
 
641
646
void st_select_lex_unit::reinit_exec_mechanism()
642
647
{
643
648
  prepared= optimized= executed= 0;
 
649
#ifndef DBUG_OFF
 
650
  if (is_union())
 
651
  {
 
652
    List_iterator_fast<Item> it(item_list);
 
653
    Item *field;
 
654
    while ((field= it++))
 
655
    {
 
656
      /*
 
657
        we can't cleanup here, because it broke link to temporary table field,
 
658
        but have to drop fixed flag to allow next fix_field of this field
 
659
        during re-executing
 
660
      */
 
661
      field->fixed= 0;
 
662
    }
 
663
  }
 
664
#endif
644
665
}
645
666
 
646
667
 
653
674
    old_result  old select_result object
654
675
 
655
676
  RETURN
656
 
    false - OK
657
 
    true  - error
 
677
    FALSE - OK
 
678
    TRUE  - error
658
679
*/
659
680
 
660
681
bool st_select_lex_unit::change_result(select_result_interceptor *new_result,
661
682
                                       select_result_interceptor *old_result)
662
683
{
663
 
  bool res= false;
 
684
  bool res= FALSE;
664
685
  for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select())
665
686
  {
666
687
    if (sl->join && sl->join->result == old_result)
667
688
      if (sl->join->change_result(new_result))
668
 
        return true;
 
689
        return TRUE;
669
690
  }
670
691
  if (fake_select_lex && fake_select_lex->join)
671
692
    res= fake_select_lex->join->change_result(new_result);
696
717
 
697
718
  if (is_union())
698
719
  {
699
 
    assert(prepared);
 
720
    DBUG_ASSERT(prepared);
700
721
    /* Types are generated during prepare */
701
722
    return &types;
702
723
  }
706
727
 
707
728
bool st_select_lex::cleanup()
708
729
{
709
 
  bool error= false;
 
730
  bool error= FALSE;
 
731
  DBUG_ENTER("st_select_lex::cleanup()");
710
732
 
711
733
  if (join)
712
734
  {
713
 
    assert((st_select_lex*)join->select_lex == this);
 
735
    DBUG_ASSERT((st_select_lex*)join->select_lex == this);
714
736
    error= join->destroy();
715
737
    delete join;
716
738
    join= 0;
722
744
  }
723
745
  non_agg_fields.empty();
724
746
  inner_refs_list.empty();
725
 
  return(error);
 
747
  DBUG_RETURN(error);
726
748
}
727
749
 
728
750