~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-07-07 13:41:07 UTC
  • mto: This revision was merged to the branch mainline in revision 2385.
  • Revision ID: olafvdspek@gmail.com-20110707134107-6mi7pauiatxtf4oe
Rename strmake to strdup (standard name)

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
 
239
242
 
240
243
  if (is_union_select)
241
244
  {
242
 
    if (!(tmp_result= union_result= new select_union))
243
 
      goto err;
 
245
    tmp_result= union_result= new select_union;
244
246
    if (describe)
245
247
      tmp_result= sel_result;
246
248
  }
266
268
    if (!join)
267
269
      goto err;
268
270
 
269
 
    session_arg->lex->current_select= sl;
 
271
    session_arg->lex().current_select= sl;
270
272
 
271
273
    can_skip_order_by= is_union_select && !(sl->braces && sl->explicit_limit);
272
274
 
275
277
                               sl->with_wild,
276
278
                               sl->where,
277
279
                               (can_skip_order_by ? 0 :
278
 
                                sl->order_list.elements) +
279
 
                               sl->group_list.elements,
 
280
                                sl->order_list.size()) +
 
281
                               sl->group_list.size(),
280
282
                               can_skip_order_by ?
281
283
                               (Order*) NULL : (Order *)sl->order_list.first,
282
284
                               (Order*) sl->group_list.first,
302
304
        field object without table.
303
305
      */
304
306
      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++))
 
307
      empty_table= (Table*) session->mem.calloc(sizeof(Table));
 
308
      types.clear();
 
309
      List<Item>::iterator it(sl->item_list.begin());
 
310
      while (Item* item_tmp= it++)
310
311
      {
311
312
        /* Error's in 'new' will be detected after loop */
312
313
        types.push_back(new Item_type_holder(session_arg, item_tmp));
317
318
    }
318
319
    else
319
320
    {
320
 
      if (types.elements != sl->item_list.elements)
 
321
      if (types.size() != sl->item_list.size())
321
322
      {
322
323
        my_message(ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT,
323
324
                   ER(ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT),MYF(0));
324
325
        goto err;
325
326
      }
326
 
      List_iterator_fast<Item> it(sl->item_list);
327
 
      List_iterator_fast<Item> tp(types);
 
327
      List<Item>::iterator it(sl->item_list.begin());
 
328
      List<Item>::iterator tp(types.begin());
328
329
      Item *type, *item_tmp;
329
330
      while ((type= tp++, item_tmp= it++))
330
331
      {
331
332
        if (((Item_type_holder*)type)->join_types(session_arg, item_tmp))
332
 
          return(true);
 
333
          return true;
333
334
      }
334
335
    }
335
336
  }
340
341
      Check that it was possible to aggregate
341
342
      all collations together for UNION.
342
343
    */
343
 
    List_iterator_fast<Item> tp(types);
 
344
    List<Item>::iterator tp(types.begin());
344
345
    Item *type;
345
346
    uint64_t create_options;
346
347
 
361
362
                                          create_options, ""))
362
363
      goto err;
363
364
    memset(&result_table_list, 0, sizeof(result_table_list));
364
 
    result_table_list.setSchemaName((char*) "");
 
365
    result_table_list.setSchemaName("", 0);
365
366
    result_table_list.alias= "union";
366
 
    result_table_list.setTableName((char *) "union");
 
367
    result_table_list.setTableName("union", 5);
367
368
    result_table_list.table= table= union_result->table;
368
369
 
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
 
    }
 
370
    session_arg->lex().current_select= lex_select_save;
 
371
    if (item_list.is_empty())
 
372
      table->fill_item_list(item_list);
376
373
    else
377
374
    {
378
375
      /*
379
376
        We're in execution of a prepared statement or stored procedure:
380
377
        reset field items to point at fields from the created temporary table.
381
378
      */
382
 
      assert(1);
 
379
      assert(false);
383
380
    }
384
381
  }
385
382
 
386
 
  session_arg->lex->current_select= lex_select_save;
 
383
  session_arg->lex().current_select= lex_select_save;
387
384
 
388
385
  return(saved_error || session_arg->is_fatal_error);
389
386
 
390
387
err:
391
 
  session_arg->lex->current_select= lex_select_save;
392
 
  return(true);
 
388
  session_arg->lex().current_select= lex_select_save;
 
389
  return true;
393
390
}
394
391
 
395
392
 
396
393
bool Select_Lex_Unit::exec()
397
394
{
398
 
  Select_Lex *lex_select_save= session->lex->current_select;
 
395
  Select_Lex *lex_select_save= session->lex().current_select;
399
396
  Select_Lex *select_cursor=first_select();
400
397
  uint64_t add_rows=0;
401
398
  ha_rows examined_rows= 0;
425
422
    for (Select_Lex *sl= select_cursor; sl; sl= sl->next_select())
426
423
    {
427
424
      ha_rows records_at_start= 0;
428
 
      session->lex->current_select= sl;
 
425
      session->lex().current_select= sl;
429
426
 
430
427
      if (optimized)
431
428
        saved_error= sl->join->reinit();
461
458
        if (sl == union_distinct)
462
459
        {
463
460
          if (table->cursor->ha_disable_indexes(HA_KEY_SWITCH_ALL))
464
 
            return(true);
 
461
            return true;
465
462
          table->no_keyread=1;
466
463
        }
467
464
        saved_error= sl->join->error;
473
470
          examined_rows+= session->examined_row_count;
474
471
          if (union_result->flush())
475
472
          {
476
 
            session->lex->current_select= lex_select_save;
477
 
            return(1);
 
473
            session->lex().current_select= lex_select_save;
 
474
            return 1;
478
475
          }
479
476
        }
480
477
      }
481
478
      if (saved_error)
482
479
      {
483
 
        session->lex->current_select= lex_select_save;
 
480
        session->lex().current_select= lex_select_save;
484
481
        return(saved_error);
485
482
      }
486
483
      /* Needed for the following test and for records_at_start in next loop */
488
485
      if (error)
489
486
      {
490
487
        table->print_error(error, MYF(0));
491
 
        return(1);
 
488
        return 1;
492
489
      }
493
490
      if (found_rows_for_union && !sl->braces &&
494
491
          select_limit_cnt != HA_POS_ERROR)
518
515
      {
519
516
        /*
520
517
          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
 
518
          select_query automatic allocation)
 
519
          TODO: The above is nonsense. select_query() will not allocate the
523
520
          join if one already exists. There must be some other reason why we
524
521
          don't let it allocate the join. Perhaps this is because we need
525
522
          some special parameter values passed to join constructor?
526
523
        */
527
 
        if (!(fake_select_lex->join= new Join(session, item_list,
528
 
                                              fake_select_lex->options, result)))
529
 
        {
530
 
          fake_select_lex->table_list.empty();
531
 
          return(true);
532
 
        }
533
 
        fake_select_lex->join->no_const_tables= true;
 
524
        fake_select_lex->join= new Join(session, item_list, fake_select_lex->options, result);
 
525
  fake_select_lex->join->no_const_tables= true;
534
526
 
535
527
        /*
536
528
          Fake Select_Lex should have item list for correctref_array
537
529
          allocation.
538
530
        */
539
531
        fake_select_lex->item_list= item_list;
540
 
        saved_error= mysql_select(session, &fake_select_lex->ref_pointer_array,
 
532
        saved_error= select_query(session, &fake_select_lex->ref_pointer_array,
541
533
                              &result_table_list,
542
534
                              0, item_list, NULL,
543
 
                              global_parameters->order_list.elements,
 
535
                              global_parameters->order_list.size(),
544
536
                              (Order*)global_parameters->order_list.first,
545
537
                              (Order*) NULL, NULL,
546
538
                              fake_select_lex->options | SELECT_NO_UNLOCK,
560
552
            to reset them back, we re-do all of the actions (yes it is ugly):
561
553
          */
562
554
                join->reset(session, item_list, fake_select_lex->options, result);
563
 
          saved_error= mysql_select(session, &fake_select_lex->ref_pointer_array,
 
555
          saved_error= select_query(session, &fake_select_lex->ref_pointer_array,
564
556
                                &result_table_list,
565
557
                                0, item_list, NULL,
566
 
                                global_parameters->order_list.elements,
 
558
                                global_parameters->order_list.size(),
567
559
                                (Order*)global_parameters->order_list.first,
568
560
                                (Order*) NULL, NULL,
569
561
                                fake_select_lex->options | SELECT_NO_UNLOCK,
577
569
        }
578
570
      }
579
571
 
580
 
      fake_select_lex->table_list.empty();
 
572
      fake_select_lex->table_list.clear();
581
573
      if (!saved_error)
582
574
      {
583
575
        session->limit_found_rows = (uint64_t)table->cursor->stats.records + add_rows;
589
581
      */
590
582
    }
591
583
  }
592
 
  session->lex->current_select= lex_select_save;
 
584
  session->lex().current_select= lex_select_save;
593
585
  return(saved_error);
594
586
}
595
587
 
600
592
 
601
593
  if (cleaned)
602
594
  {
603
 
    return(false);
 
595
    return false;
604
596
  }
605
597
  cleaned= 1;
606
598
 
607
599
  if (union_result)
608
600
  {
609
 
    delete union_result;
610
 
    union_result=0; // Safety
 
601
    safe_delete(union_result);
611
602
    table= 0; // Safety
612
603
  }
613
604
 
623
614
      join->tables= 0;
624
615
    }
625
616
    error|= fake_select_lex->cleanup();
626
 
    if (fake_select_lex->order_list.elements)
 
617
    if (fake_select_lex->order_list.size())
627
618
    {
628
619
      Order *ord;
629
620
      for (ord= (Order*)fake_select_lex->order_list.first; ord; ord= ord->next)
709
700
  {
710
701
    assert((Select_Lex*)join->select_lex == this);
711
702
    error= join->destroy();
712
 
    delete join;
713
 
    join= 0;
 
703
    safe_delete(join);
714
704
  }
715
705
  for (Select_Lex_Unit *lex_unit= first_inner_unit(); lex_unit ;
716
706
       lex_unit= lex_unit->next_unit())
717
707
  {
718
708
    error= (bool) ((uint32_t) error | (uint32_t) lex_unit->cleanup());
719
709
  }
720
 
  non_agg_fields.empty();
721
 
  inner_refs_list.empty();
 
710
  non_agg_fields.clear();
 
711
  inner_refs_list.clear();
722
712
  return(error);
723
713
}
724
714