~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_union.cc

  • Committer: Olaf van der Spek
  • Date: 2011-06-23 11:44:30 UTC
  • mto: This revision was merged to the branch mainline in revision 2348.
  • Revision ID: olafvdspek@gmail.com-20110623114430-no355yypk4y3icqb
Refactor

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 <config.h>
 
21
 
21
22
#include <drizzled/sql_select.h>
22
23
#include <drizzled/error.h>
23
24
#include <drizzled/item/type_holder.h>
24
25
#include <drizzled/sql_base.h>
25
26
#include <drizzled/sql_union.h>
 
27
#include <drizzled/select_union.h>
 
28
#include <drizzled/sql_lex.h>
 
29
#include <drizzled/session.h>
 
30
#include <drizzled/item/subselect.h>
26
31
 
27
 
namespace drizzled
28
 
{
 
32
namespace drizzled {
29
33
 
30
34
bool drizzle_union(Session *session, LEX *, select_result *result,
31
35
                   Select_Lex_Unit *unit, uint64_t setup_tables_done_option)
32
36
{
33
 
  bool res;
34
 
  if (!(res= unit->prepare(session, result, SELECT_NO_UNLOCK |
35
 
                           setup_tables_done_option)))
 
37
  bool res= unit->prepare(session, result, SELECT_NO_UNLOCK | setup_tables_done_option);
 
38
  if (not res)
36
39
    res= unit->exec();
37
40
  if (res)
38
 
    res|= unit->cleanup();
39
 
  return(res);
 
41
    unit->cleanup();
 
42
  return res;
40
43
}
41
44
 
42
45
 
122
125
{
123
126
  assert(table == NULL);
124
127
  tmp_table_param.init();
125
 
  tmp_table_param.field_count= column_types->elements;
 
128
  tmp_table_param.field_count= column_types->size();
126
129
 
127
130
  if (! (table= create_tmp_table(session_arg, &tmp_table_param, *column_types,
128
131
                                 (Order*) NULL, is_union_distinct, 1,
168
171
void
169
172
Select_Lex_Unit::init_prepare_fake_select_lex(Session *session_arg)
170
173
{
171
 
  session_arg->lex->current_select= fake_select_lex;
 
174
  session_arg->lex().current_select= fake_select_lex;
172
175
  fake_select_lex->table_list.link_in_list((unsigned char *)&result_table_list,
173
176
                                           (unsigned char **)
174
177
                                           &result_table_list.next_local);
194
197
bool Select_Lex_Unit::prepare(Session *session_arg, select_result *sel_result,
195
198
                              uint64_t additional_options)
196
199
{
197
 
  Select_Lex *lex_select_save= session_arg->lex->current_select;
 
200
  Select_Lex *lex_select_save= session_arg->lex().current_select;
198
201
  Select_Lex *sl, *first_sl= first_select();
199
202
  select_result *tmp_result;
200
203
  bool is_union_select;
220
223
        offset_limit_cnt= 0;
221
224
        if (result->prepare(sl->join->fields_list, this))
222
225
        {
223
 
          return(true);
 
226
          return true;
224
227
        }
225
228
        sl->join->select_options|= SELECT_DESCRIBE;
226
229
        sl->join->reinit();
227
230
      }
228
231
    }
229
 
    return(false);
 
232
    return false;
230
233
  }
231
234
  prepared= 1;
232
235
  saved_error= false;
233
236
 
234
 
  session_arg->lex->current_select= sl= first_sl;
 
237
  session_arg->lex().current_select= sl= first_sl;
235
238
  found_rows_for_union= first_sl->options & OPTION_FOUND_ROWS;
236
239
  is_union_select= is_union() || fake_select_lex;
237
240
 
266
269
    if (!join)
267
270
      goto err;
268
271
 
269
 
    session_arg->lex->current_select= sl;
 
272
    session_arg->lex().current_select= sl;
270
273
 
271
274
    can_skip_order_by= is_union_select && !(sl->braces && sl->explicit_limit);
272
275
 
275
278
                               sl->with_wild,
276
279
                               sl->where,
277
280
                               (can_skip_order_by ? 0 :
278
 
                                sl->order_list.elements) +
279
 
                               sl->group_list.elements,
 
281
                                sl->order_list.size()) +
 
282
                               sl->group_list.size(),
280
283
                               can_skip_order_by ?
281
284
                               (Order*) NULL : (Order *)sl->order_list.first,
282
285
                               (Order*) sl->group_list.first,
302
305
        field object without table.
303
306
      */
304
307
      assert(!empty_table);
305
 
      empty_table= (Table*) session->calloc(sizeof(Table));
306
 
      types.empty();
307
 
      List_iterator_fast<Item> it(sl->item_list);
308
 
      Item *item_tmp;
309
 
      while ((item_tmp= it++))
 
308
      empty_table= (Table*) session->mem.calloc(sizeof(Table));
 
309
      types.clear();
 
310
      List<Item>::iterator it(sl->item_list.begin());
 
311
      while (Item* item_tmp= it++)
310
312
      {
311
313
        /* Error's in 'new' will be detected after loop */
312
314
        types.push_back(new Item_type_holder(session_arg, item_tmp));
317
319
    }
318
320
    else
319
321
    {
320
 
      if (types.elements != sl->item_list.elements)
 
322
      if (types.size() != sl->item_list.size())
321
323
      {
322
324
        my_message(ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT,
323
325
                   ER(ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT),MYF(0));
324
326
        goto err;
325
327
      }
326
 
      List_iterator_fast<Item> it(sl->item_list);
327
 
      List_iterator_fast<Item> tp(types);
 
328
      List<Item>::iterator it(sl->item_list.begin());
 
329
      List<Item>::iterator tp(types.begin());
328
330
      Item *type, *item_tmp;
329
331
      while ((type= tp++, item_tmp= it++))
330
332
      {
331
333
        if (((Item_type_holder*)type)->join_types(session_arg, item_tmp))
332
 
          return(true);
 
334
          return true;
333
335
      }
334
336
    }
335
337
  }
340
342
      Check that it was possible to aggregate
341
343
      all collations together for UNION.
342
344
    */
343
 
    List_iterator_fast<Item> tp(types);
 
345
    List<Item>::iterator tp(types.begin());
344
346
    Item *type;
345
347
    uint64_t create_options;
346
348
 
366
368
    result_table_list.setTableName((char *) "union");
367
369
    result_table_list.table= table= union_result->table;
368
370
 
369
 
    session_arg->lex->current_select= lex_select_save;
370
 
    if (!item_list.elements)
371
 
    {
372
 
      saved_error= table->fill_item_list(&item_list);
373
 
      if (saved_error)
374
 
        goto err;
375
 
    }
 
371
    session_arg->lex().current_select= lex_select_save;
 
372
    if (item_list.is_empty())
 
373
      table->fill_item_list(item_list);
376
374
    else
377
375
    {
378
376
      /*
379
377
        We're in execution of a prepared statement or stored procedure:
380
378
        reset field items to point at fields from the created temporary table.
381
379
      */
382
 
      assert(1);
 
380
      assert(1); // Olaf: should this be assert(false)?
383
381
    }
384
382
  }
385
383
 
386
 
  session_arg->lex->current_select= lex_select_save;
 
384
  session_arg->lex().current_select= lex_select_save;
387
385
 
388
386
  return(saved_error || session_arg->is_fatal_error);
389
387
 
390
388
err:
391
 
  session_arg->lex->current_select= lex_select_save;
392
 
  return(true);
 
389
  session_arg->lex().current_select= lex_select_save;
 
390
  return true;
393
391
}
394
392
 
395
393
 
396
394
bool Select_Lex_Unit::exec()
397
395
{
398
 
  Select_Lex *lex_select_save= session->lex->current_select;
 
396
  Select_Lex *lex_select_save= session->lex().current_select;
399
397
  Select_Lex *select_cursor=first_select();
400
398
  uint64_t add_rows=0;
401
399
  ha_rows examined_rows= 0;
425
423
    for (Select_Lex *sl= select_cursor; sl; sl= sl->next_select())
426
424
    {
427
425
      ha_rows records_at_start= 0;
428
 
      session->lex->current_select= sl;
 
426
      session->lex().current_select= sl;
429
427
 
430
428
      if (optimized)
431
429
        saved_error= sl->join->reinit();
461
459
        if (sl == union_distinct)
462
460
        {
463
461
          if (table->cursor->ha_disable_indexes(HA_KEY_SWITCH_ALL))
464
 
            return(true);
 
462
            return true;
465
463
          table->no_keyread=1;
466
464
        }
467
465
        saved_error= sl->join->error;
473
471
          examined_rows+= session->examined_row_count;
474
472
          if (union_result->flush())
475
473
          {
476
 
            session->lex->current_select= lex_select_save;
 
474
            session->lex().current_select= lex_select_save;
477
475
            return(1);
478
476
          }
479
477
        }
480
478
      }
481
479
      if (saved_error)
482
480
      {
483
 
        session->lex->current_select= lex_select_save;
 
481
        session->lex().current_select= lex_select_save;
484
482
        return(saved_error);
485
483
      }
486
484
      /* Needed for the following test and for records_at_start in next loop */
518
516
      {
519
517
        /*
520
518
          allocate JOIN for fake select only once (prevent
521
 
          mysql_select automatic allocation)
522
 
          TODO: The above is nonsense. mysql_select() will not allocate the
 
519
          select_query automatic allocation)
 
520
          TODO: The above is nonsense. select_query() will not allocate the
523
521
          join if one already exists. There must be some other reason why we
524
522
          don't let it allocate the join. Perhaps this is because we need
525
523
          some special parameter values passed to join constructor?
527
525
        if (!(fake_select_lex->join= new Join(session, item_list,
528
526
                                              fake_select_lex->options, result)))
529
527
        {
530
 
          fake_select_lex->table_list.empty();
531
 
          return(true);
 
528
          fake_select_lex->table_list.clear();
 
529
          return true;
532
530
        }
533
531
        fake_select_lex->join->no_const_tables= true;
534
532
 
537
535
          allocation.
538
536
        */
539
537
        fake_select_lex->item_list= item_list;
540
 
        saved_error= mysql_select(session, &fake_select_lex->ref_pointer_array,
 
538
        saved_error= select_query(session, &fake_select_lex->ref_pointer_array,
541
539
                              &result_table_list,
542
540
                              0, item_list, NULL,
543
 
                              global_parameters->order_list.elements,
 
541
                              global_parameters->order_list.size(),
544
542
                              (Order*)global_parameters->order_list.first,
545
543
                              (Order*) NULL, NULL,
546
544
                              fake_select_lex->options | SELECT_NO_UNLOCK,
560
558
            to reset them back, we re-do all of the actions (yes it is ugly):
561
559
          */
562
560
                join->reset(session, item_list, fake_select_lex->options, result);
563
 
          saved_error= mysql_select(session, &fake_select_lex->ref_pointer_array,
 
561
          saved_error= select_query(session, &fake_select_lex->ref_pointer_array,
564
562
                                &result_table_list,
565
563
                                0, item_list, NULL,
566
 
                                global_parameters->order_list.elements,
 
564
                                global_parameters->order_list.size(),
567
565
                                (Order*)global_parameters->order_list.first,
568
566
                                (Order*) NULL, NULL,
569
567
                                fake_select_lex->options | SELECT_NO_UNLOCK,
577
575
        }
578
576
      }
579
577
 
580
 
      fake_select_lex->table_list.empty();
 
578
      fake_select_lex->table_list.clear();
581
579
      if (!saved_error)
582
580
      {
583
581
        session->limit_found_rows = (uint64_t)table->cursor->stats.records + add_rows;
589
587
      */
590
588
    }
591
589
  }
592
 
  session->lex->current_select= lex_select_save;
 
590
  session->lex().current_select= lex_select_save;
593
591
  return(saved_error);
594
592
}
595
593
 
600
598
 
601
599
  if (cleaned)
602
600
  {
603
 
    return(false);
 
601
    return false;
604
602
  }
605
603
  cleaned= 1;
606
604
 
607
605
  if (union_result)
608
606
  {
609
 
    delete union_result;
610
 
    union_result=0; // Safety
 
607
    safe_delete(union_result);
611
608
    table= 0; // Safety
612
609
  }
613
610
 
623
620
      join->tables= 0;
624
621
    }
625
622
    error|= fake_select_lex->cleanup();
626
 
    if (fake_select_lex->order_list.elements)
 
623
    if (fake_select_lex->order_list.size())
627
624
    {
628
625
      Order *ord;
629
626
      for (ord= (Order*)fake_select_lex->order_list.first; ord; ord= ord->next)
709
706
  {
710
707
    assert((Select_Lex*)join->select_lex == this);
711
708
    error= join->destroy();
712
 
    delete join;
713
 
    join= 0;
 
709
    safe_delete(join);
714
710
  }
715
711
  for (Select_Lex_Unit *lex_unit= first_inner_unit(); lex_unit ;
716
712
       lex_unit= lex_unit->next_unit())
717
713
  {
718
714
    error= (bool) ((uint32_t) error | (uint32_t) lex_unit->cleanup());
719
715
  }
720
 
  non_agg_fields.empty();
721
 
  inner_refs_list.empty();
 
716
  non_agg_fields.clear();
 
717
  inner_refs_list.clear();
722
718
  return(error);
723
719
}
724
720