~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_union.cc

  • Committer: Mark Atwood
  • Date: 2011-08-12 04:08:33 UTC
  • mfrom: (2385.2.17 refactor5)
  • Revision ID: me@mark.atwood.name-20110812040833-u6j85nc6ahuc0dtz
mergeĀ lp:~olafvdspek/drizzle/refactor5

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
 
354
355
      }
355
356
    }
356
357
 
357
 
    create_options= (first_sl->options | session_arg->options |
358
 
                     TMP_TABLE_ALL_COLUMNS);
 
358
    create_options= first_sl->options | session_arg->options | TMP_TABLE_ALL_COLUMNS;
359
359
 
360
 
    if (union_result->create_result_table(session, &types, test(union_distinct),
361
 
                                          create_options, ""))
 
360
    if (union_result->create_result_table(session, &types, test(union_distinct), create_options, ""))
362
361
      goto err;
363
362
    memset(&result_table_list, 0, sizeof(result_table_list));
364
 
    result_table_list.setSchemaName((char*) "");
 
363
    result_table_list.setSchemaName("");
365
364
    result_table_list.alias= "union";
366
 
    result_table_list.setTableName((char *) "union");
 
365
    result_table_list.setTableName("union");
367
366
    result_table_list.table= table= union_result->table;
368
367
 
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
 
    }
 
368
    session_arg->lex().current_select= lex_select_save;
 
369
    if (item_list.is_empty())
 
370
      table->fill_item_list(item_list);
376
371
    else
377
372
    {
378
373
      /*
379
374
        We're in execution of a prepared statement or stored procedure:
380
375
        reset field items to point at fields from the created temporary table.
381
376
      */
382
 
      assert(1);
 
377
      assert(false);
383
378
    }
384
379
  }
385
380
 
386
 
  session_arg->lex->current_select= lex_select_save;
 
381
  session_arg->lex().current_select= lex_select_save;
387
382
 
388
383
  return(saved_error || session_arg->is_fatal_error);
389
384
 
390
385
err:
391
 
  session_arg->lex->current_select= lex_select_save;
392
 
  return(true);
 
386
  session_arg->lex().current_select= lex_select_save;
 
387
  return true;
393
388
}
394
389
 
395
390
 
396
391
bool Select_Lex_Unit::exec()
397
392
{
398
 
  Select_Lex *lex_select_save= session->lex->current_select;
 
393
  Select_Lex *lex_select_save= session->lex().current_select;
399
394
  Select_Lex *select_cursor=first_select();
400
395
  uint64_t add_rows=0;
401
396
  ha_rows examined_rows= 0;
425
420
    for (Select_Lex *sl= select_cursor; sl; sl= sl->next_select())
426
421
    {
427
422
      ha_rows records_at_start= 0;
428
 
      session->lex->current_select= sl;
 
423
      session->lex().current_select= sl;
429
424
 
430
425
      if (optimized)
431
426
        saved_error= sl->join->reinit();
461
456
        if (sl == union_distinct)
462
457
        {
463
458
          if (table->cursor->ha_disable_indexes(HA_KEY_SWITCH_ALL))
464
 
            return(true);
 
459
            return true;
465
460
          table->no_keyread=1;
466
461
        }
467
462
        saved_error= sl->join->error;
473
468
          examined_rows+= session->examined_row_count;
474
469
          if (union_result->flush())
475
470
          {
476
 
            session->lex->current_select= lex_select_save;
477
 
            return(1);
 
471
            session->lex().current_select= lex_select_save;
 
472
            return 1;
478
473
          }
479
474
        }
480
475
      }
481
476
      if (saved_error)
482
477
      {
483
 
        session->lex->current_select= lex_select_save;
 
478
        session->lex().current_select= lex_select_save;
484
479
        return(saved_error);
485
480
      }
486
481
      /* Needed for the following test and for records_at_start in next loop */
488
483
      if (error)
489
484
      {
490
485
        table->print_error(error, MYF(0));
491
 
        return(1);
 
486
        return 1;
492
487
      }
493
488
      if (found_rows_for_union && !sl->braces &&
494
489
          select_limit_cnt != HA_POS_ERROR)
524
519
          don't let it allocate the join. Perhaps this is because we need
525
520
          some special parameter values passed to join constructor?
526
521
        */
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;
 
522
        fake_select_lex->join= new Join(session, item_list, fake_select_lex->options, result);
 
523
  fake_select_lex->join->no_const_tables= true;
534
524
 
535
525
        /*
536
526
          Fake Select_Lex should have item list for correctref_array
540
530
        saved_error= select_query(session, &fake_select_lex->ref_pointer_array,
541
531
                              &result_table_list,
542
532
                              0, item_list, NULL,
543
 
                              global_parameters->order_list.elements,
 
533
                              global_parameters->order_list.size(),
544
534
                              (Order*)global_parameters->order_list.first,
545
535
                              (Order*) NULL, NULL,
546
536
                              fake_select_lex->options | SELECT_NO_UNLOCK,
563
553
          saved_error= select_query(session, &fake_select_lex->ref_pointer_array,
564
554
                                &result_table_list,
565
555
                                0, item_list, NULL,
566
 
                                global_parameters->order_list.elements,
 
556
                                global_parameters->order_list.size(),
567
557
                                (Order*)global_parameters->order_list.first,
568
558
                                (Order*) NULL, NULL,
569
559
                                fake_select_lex->options | SELECT_NO_UNLOCK,
577
567
        }
578
568
      }
579
569
 
580
 
      fake_select_lex->table_list.empty();
 
570
      fake_select_lex->table_list.clear();
581
571
      if (!saved_error)
582
572
      {
583
573
        session->limit_found_rows = (uint64_t)table->cursor->stats.records + add_rows;
589
579
      */
590
580
    }
591
581
  }
592
 
  session->lex->current_select= lex_select_save;
 
582
  session->lex().current_select= lex_select_save;
593
583
  return(saved_error);
594
584
}
595
585
 
600
590
 
601
591
  if (cleaned)
602
592
  {
603
 
    return(false);
 
593
    return false;
604
594
  }
605
595
  cleaned= 1;
606
596
 
607
597
  if (union_result)
608
598
  {
609
 
    delete union_result;
610
 
    union_result=0; // Safety
 
599
    safe_delete(union_result);
611
600
    table= 0; // Safety
612
601
  }
613
602
 
623
612
      join->tables= 0;
624
613
    }
625
614
    error|= fake_select_lex->cleanup();
626
 
    if (fake_select_lex->order_list.elements)
 
615
    if (fake_select_lex->order_list.size())
627
616
    {
628
617
      Order *ord;
629
618
      for (ord= (Order*)fake_select_lex->order_list.first; ord; ord= ord->next)
709
698
  {
710
699
    assert((Select_Lex*)join->select_lex == this);
711
700
    error= join->destroy();
712
 
    delete join;
713
 
    join= 0;
 
701
    safe_delete(join);
714
702
  }
715
703
  for (Select_Lex_Unit *lex_unit= first_inner_unit(); lex_unit ;
716
704
       lex_unit= lex_unit->next_unit())
717
705
  {
718
706
    error= (bool) ((uint32_t) error | (uint32_t) lex_unit->cleanup());
719
707
  }
720
 
  non_agg_fields.empty();
721
 
  inner_refs_list.empty();
 
708
  non_agg_fields.clear();
 
709
  inner_refs_list.clear();
722
710
  return(error);
723
711
}
724
712