~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_union.cc

Does not work (compile issue in plugin).

Show diffs side-by-side

added added

removed removed

Lines of Context:
11
11
 
12
12
   You should have received a copy of the GNU General Public License
13
13
   along with this program; if not, write to the Free Software
14
 
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
 
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
15
 
16
16
/*
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>
21
 
 
 
20
#include "config.h"
22
21
#include <drizzled/sql_select.h>
23
22
#include <drizzled/error.h>
24
23
#include <drizzled/item/type_holder.h>
25
24
#include <drizzled/sql_base.h>
26
25
#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>
31
26
 
32
27
namespace drizzled
33
28
{
64
59
    unit->offset_limit_cnt--;
65
60
    return 0;
66
61
  }
67
 
  fill_record(session, table->getFields(), values, true);
 
62
  fill_record(session, table->field, values, true);
68
63
  if (session->is_error())
69
64
    return 1;
70
65
 
71
 
  if ((error= table->cursor->insertRecord(table->getInsertRecord())))
 
66
  if ((error= table->cursor->ha_write_row(table->record[0])))
72
67
  {
73
68
    /* create_myisam_from_heap will generate error if needed */
74
 
    if (table->cursor->is_fatal_error(error, HA_CHECK_DUP))
75
 
    {
76
 
      my_error(ER_USE_SQL_BIG_RESULT, MYF(0));
77
 
      return true;
78
 
    }
 
69
    if (table->cursor->is_fatal_error(error, HA_CHECK_DUP) &&
 
70
        create_myisam_from_heap(session, table, tmp_table_param.start_recinfo,
 
71
                                &tmp_table_param.recinfo, error, 1))
 
72
      return 1;
79
73
  }
80
74
  return 0;
81
75
}
110
104
                         duplicates on insert
111
105
      options            create options
112
106
      table_alias        name of the temporary table
 
107
      bit_fields_as_long convert bit fields to uint64_t
113
108
 
114
109
  DESCRIPTION
115
110
    Create a temporary table that is used to store the result of a UNION,
123
118
bool
124
119
select_union::create_result_table(Session *session_arg, List<Item> *column_types,
125
120
                                  bool is_union_distinct, uint64_t options,
126
 
                                  const char *table_alias)
 
121
                                  const char *table_alias,
 
122
                                  bool bit_fields_as_long)
127
123
{
128
 
  assert(table == NULL);
 
124
  assert(table == 0);
129
125
  tmp_table_param.init();
130
 
  tmp_table_param.field_count= column_types->size();
 
126
  tmp_table_param.field_count= column_types->elements;
 
127
  tmp_table_param.bit_fields_as_long= bit_fields_as_long;
131
128
 
132
129
  if (! (table= create_tmp_table(session_arg, &tmp_table_param, *column_types,
133
 
                                 (Order*) NULL, is_union_distinct, 1,
 
130
                                 (order_st*) 0, is_union_distinct, 1,
134
131
                                 options, HA_POS_ERROR, (char*) table_alias)))
135
 
  {
136
132
    return true;
137
 
  }
138
 
 
139
133
  table->cursor->extra(HA_EXTRA_WRITE_CACHE);
140
134
  table->cursor->extra(HA_EXTRA_IGNORE_DUP_KEY);
141
 
 
142
135
  return false;
143
136
}
144
137
 
173
166
void
174
167
Select_Lex_Unit::init_prepare_fake_select_lex(Session *session_arg)
175
168
{
176
 
  session_arg->lex().current_select= fake_select_lex;
 
169
  session_arg->lex->current_select= fake_select_lex;
177
170
  fake_select_lex->table_list.link_in_list((unsigned char *)&result_table_list,
178
171
                                           (unsigned char **)
179
172
                                           &result_table_list.next_local);
181
174
    fake_select_lex->context.first_name_resolution_table=
182
175
    fake_select_lex->get_table_list();
183
176
 
184
 
  for (Order *order= (Order *) global_parameters->order_list.first;
 
177
  for (order_st *order= (order_st *) global_parameters->order_list.first;
185
178
       order;
186
179
       order= order->next)
187
180
    order->item= &order->item_ptr;
188
181
 
189
 
  for (Order *order= (Order *)global_parameters->order_list.first;
 
182
  for (order_st *order= (order_st *)global_parameters->order_list.first;
190
183
       order;
191
184
       order=order->next)
192
185
  {
199
192
bool Select_Lex_Unit::prepare(Session *session_arg, select_result *sel_result,
200
193
                              uint64_t additional_options)
201
194
{
202
 
  Select_Lex *lex_select_save= session_arg->lex().current_select;
 
195
  Select_Lex *lex_select_save= session_arg->lex->current_select;
203
196
  Select_Lex *sl, *first_sl= first_select();
204
197
  select_result *tmp_result;
205
198
  bool is_union_select;
236
229
  prepared= 1;
237
230
  saved_error= false;
238
231
 
239
 
  session_arg->lex().current_select= sl= first_sl;
 
232
  session_arg->lex->current_select= sl= first_sl;
240
233
  found_rows_for_union= first_sl->options & OPTION_FOUND_ROWS;
241
234
  is_union_select= is_union() || fake_select_lex;
242
235
 
258
251
  {
259
252
    bool can_skip_order_by;
260
253
    sl->options|=  SELECT_NO_UNLOCK;
261
 
    Join *join= new Join(session_arg, sl->item_list,
 
254
    JOIN *join= new JOIN(session_arg, sl->item_list,
262
255
                         sl->options | session_arg->options | additional_options,
263
256
                         tmp_result);
264
257
    /*
271
264
    if (!join)
272
265
      goto err;
273
266
 
274
 
    session_arg->lex().current_select= sl;
 
267
    session_arg->lex->current_select= sl;
275
268
 
276
269
    can_skip_order_by= is_union_select && !(sl->braces && sl->explicit_limit);
277
270
 
280
273
                               sl->with_wild,
281
274
                               sl->where,
282
275
                               (can_skip_order_by ? 0 :
283
 
                                sl->order_list.size()) +
284
 
                               sl->group_list.size(),
 
276
                                sl->order_list.elements) +
 
277
                               sl->group_list.elements,
285
278
                               can_skip_order_by ?
286
 
                               (Order*) NULL : (Order *)sl->order_list.first,
287
 
                               (Order*) sl->group_list.first,
 
279
                               (order_st*) 0 : (order_st *)sl->order_list.first,
 
280
                               (order_st*) sl->group_list.first,
288
281
                               sl->having,
289
282
                               sl, this);
290
283
    /* There are no * in the statement anymore (for PS) */
308
301
      */
309
302
      assert(!empty_table);
310
303
      empty_table= (Table*) session->calloc(sizeof(Table));
311
 
      types.clear();
312
 
      List<Item>::iterator it(sl->item_list.begin());
 
304
      types.empty();
 
305
      List_iterator_fast<Item> it(sl->item_list);
313
306
      Item *item_tmp;
314
307
      while ((item_tmp= it++))
315
308
      {
322
315
    }
323
316
    else
324
317
    {
325
 
      if (types.size() != sl->item_list.size())
 
318
      if (types.elements != sl->item_list.elements)
326
319
      {
327
320
        my_message(ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT,
328
321
                   ER(ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT),MYF(0));
329
322
        goto err;
330
323
      }
331
 
      List<Item>::iterator it(sl->item_list.begin());
332
 
      List<Item>::iterator tp(types.begin());
 
324
      List_iterator_fast<Item> it(sl->item_list);
 
325
      List_iterator_fast<Item> tp(types);
333
326
      Item *type, *item_tmp;
334
327
      while ((type= tp++, item_tmp= it++))
335
328
      {
345
338
      Check that it was possible to aggregate
346
339
      all collations together for UNION.
347
340
    */
348
 
    List<Item>::iterator tp(types.begin());
 
341
    List_iterator_fast<Item> tp(types);
349
342
    Item *type;
350
343
    uint64_t create_options;
351
344
 
363
356
                     TMP_TABLE_ALL_COLUMNS);
364
357
 
365
358
    if (union_result->create_result_table(session, &types, test(union_distinct),
366
 
                                          create_options, ""))
 
359
                                          create_options, "", false))
367
360
      goto err;
368
361
    memset(&result_table_list, 0, sizeof(result_table_list));
369
 
    result_table_list.setSchemaName((char*) "");
 
362
    result_table_list.db= (char*) "";
370
363
    result_table_list.alias= "union";
371
 
    result_table_list.setTableName((char *) "union");
 
364
    result_table_list.table_name= (char *) "union";
372
365
    result_table_list.table= table= union_result->table;
373
366
 
374
 
    session_arg->lex().current_select= lex_select_save;
375
 
    if (item_list.is_empty())
376
 
      table->fill_item_list(item_list);
 
367
    session_arg->lex->current_select= lex_select_save;
 
368
    if (!item_list.elements)
 
369
    {
 
370
      saved_error= table->fill_item_list(&item_list);
 
371
      if (saved_error)
 
372
        goto err;
 
373
    }
377
374
    else
378
375
    {
379
376
      /*
380
377
        We're in execution of a prepared statement or stored procedure:
381
378
        reset field items to point at fields from the created temporary table.
382
379
      */
383
 
      assert(1); // Olaf: should this be assert(false)?
 
380
      assert(1);
384
381
    }
385
382
  }
386
383
 
387
 
  session_arg->lex().current_select= lex_select_save;
 
384
  session_arg->lex->current_select= lex_select_save;
388
385
 
389
386
  return(saved_error || session_arg->is_fatal_error);
390
387
 
391
388
err:
392
 
  session_arg->lex().current_select= lex_select_save;
 
389
  session_arg->lex->current_select= lex_select_save;
393
390
  return(true);
394
391
}
395
392
 
396
393
 
397
394
bool Select_Lex_Unit::exec()
398
395
{
399
 
  Select_Lex *lex_select_save= session->lex().current_select;
 
396
  Select_Lex *lex_select_save= session->lex->current_select;
400
397
  Select_Lex *select_cursor=first_select();
401
398
  uint64_t add_rows=0;
402
399
  ha_rows examined_rows= 0;
403
400
 
404
 
  if (executed && uncacheable.none() && ! describe)
405
 
    return false;
 
401
  if (executed && !uncacheable && !describe)
 
402
    return(false);
406
403
  executed= 1;
407
404
 
408
 
  if (uncacheable.any() || ! item || ! item->assigned() || describe)
 
405
  if (uncacheable || !item || !item->assigned() || describe)
409
406
  {
410
407
    if (item)
411
408
      item->reset_value_registration();
426
423
    for (Select_Lex *sl= select_cursor; sl; sl= sl->next_select())
427
424
    {
428
425
      ha_rows records_at_start= 0;
429
 
      session->lex().current_select= sl;
 
426
      session->lex->current_select= sl;
430
427
 
431
428
      if (optimized)
432
429
        saved_error= sl->join->reinit();
437
434
        {
438
435
          offset_limit_cnt= 0;
439
436
          /*
440
 
            We can't use LIMIT at this stage if we are using ORDER BY for the
 
437
            We can't use LIMIT at this stage if we are using order_st BY for the
441
438
            whole query
442
439
          */
443
440
          if (sl->order_list.first || describe)
474
471
          examined_rows+= session->examined_row_count;
475
472
          if (union_result->flush())
476
473
          {
477
 
            session->lex().current_select= lex_select_save;
 
474
            session->lex->current_select= lex_select_save;
478
475
            return(1);
479
476
          }
480
477
        }
481
478
      }
482
479
      if (saved_error)
483
480
      {
484
 
        session->lex().current_select= lex_select_save;
 
481
        session->lex->current_select= lex_select_save;
485
482
        return(saved_error);
486
483
      }
487
484
      /* Needed for the following test and for records_at_start in next loop */
514
511
    {
515
512
      set_limit(global_parameters);
516
513
      init_prepare_fake_select_lex(session);
517
 
      Join *join= fake_select_lex->join;
 
514
      JOIN *join= fake_select_lex->join;
518
515
      if (!join)
519
516
      {
520
517
        /*
521
518
          allocate JOIN for fake select only once (prevent
522
 
          select_query automatic allocation)
523
 
          TODO: The above is nonsense. select_query() will not allocate the
 
519
          mysql_select automatic allocation)
 
520
          TODO: The above is nonsense. mysql_select() will not allocate the
524
521
          join if one already exists. There must be some other reason why we
525
522
          don't let it allocate the join. Perhaps this is because we need
526
523
          some special parameter values passed to join constructor?
527
524
        */
528
 
        if (!(fake_select_lex->join= new Join(session, item_list,
 
525
        if (!(fake_select_lex->join= new JOIN(session, item_list,
529
526
                                              fake_select_lex->options, result)))
530
527
        {
531
 
          fake_select_lex->table_list.clear();
 
528
          fake_select_lex->table_list.empty();
532
529
          return(true);
533
530
        }
534
531
        fake_select_lex->join->no_const_tables= true;
538
535
          allocation.
539
536
        */
540
537
        fake_select_lex->item_list= item_list;
541
 
        saved_error= select_query(session, &fake_select_lex->ref_pointer_array,
 
538
        saved_error= mysql_select(session, &fake_select_lex->ref_pointer_array,
542
539
                              &result_table_list,
543
540
                              0, item_list, NULL,
544
 
                              global_parameters->order_list.size(),
545
 
                              (Order*)global_parameters->order_list.first,
546
 
                              (Order*) NULL, NULL,
 
541
                              global_parameters->order_list.elements,
 
542
                              (order_st*)global_parameters->order_list.first,
 
543
                              (order_st*) NULL, NULL,
547
544
                              fake_select_lex->options | SELECT_NO_UNLOCK,
548
545
                              result, this, fake_select_lex);
549
546
      }
561
558
            to reset them back, we re-do all of the actions (yes it is ugly):
562
559
          */
563
560
                join->reset(session, item_list, fake_select_lex->options, result);
564
 
          saved_error= select_query(session, &fake_select_lex->ref_pointer_array,
 
561
          saved_error= mysql_select(session, &fake_select_lex->ref_pointer_array,
565
562
                                &result_table_list,
566
563
                                0, item_list, NULL,
567
 
                                global_parameters->order_list.size(),
568
 
                                (Order*)global_parameters->order_list.first,
569
 
                                (Order*) NULL, NULL,
 
564
                                global_parameters->order_list.elements,
 
565
                                (order_st*)global_parameters->order_list.first,
 
566
                                (order_st*) NULL, NULL,
570
567
                                fake_select_lex->options | SELECT_NO_UNLOCK,
571
568
                                result, this, fake_select_lex);
572
569
        }
578
575
        }
579
576
      }
580
577
 
581
 
      fake_select_lex->table_list.clear();
 
578
      fake_select_lex->table_list.empty();
582
579
      if (!saved_error)
583
580
      {
584
581
        session->limit_found_rows = (uint64_t)table->cursor->stats.records + add_rows;
590
587
      */
591
588
    }
592
589
  }
593
 
  session->lex().current_select= lex_select_save;
 
590
  session->lex->current_select= lex_select_save;
594
591
  return(saved_error);
595
592
}
596
593
 
607
604
 
608
605
  if (union_result)
609
606
  {
610
 
    safe_delete(union_result);
 
607
    delete union_result;
 
608
    union_result=0; // Safety
 
609
    if (table)
 
610
      table->free_tmp_table(session);
611
611
    table= 0; // Safety
612
612
  }
613
613
 
616
616
 
617
617
  if (fake_select_lex)
618
618
  {
619
 
    Join *join;
 
619
    JOIN *join;
620
620
    if ((join= fake_select_lex->join))
621
621
    {
622
622
      join->tables_list= 0;
623
623
      join->tables= 0;
624
624
    }
625
625
    error|= fake_select_lex->cleanup();
626
 
    if (fake_select_lex->order_list.size())
 
626
    if (fake_select_lex->order_list.elements)
627
627
    {
628
 
      Order *ord;
629
 
      for (ord= (Order*)fake_select_lex->order_list.first; ord; ord= ord->next)
 
628
      order_st *ord;
 
629
      for (ord= (order_st*)fake_select_lex->order_list.first; ord; ord= ord->next)
630
630
        (*ord->item)->cleanup();
631
631
    }
632
632
  }
709
709
  {
710
710
    assert((Select_Lex*)join->select_lex == this);
711
711
    error= join->destroy();
712
 
    safe_delete(join);
 
712
    delete join;
 
713
    join= 0;
713
714
  }
714
715
  for (Select_Lex_Unit *lex_unit= first_inner_unit(); lex_unit ;
715
716
       lex_unit= lex_unit->next_unit())
716
717
  {
717
718
    error= (bool) ((uint32_t) error | (uint32_t) lex_unit->cleanup());
718
719
  }
719
 
  non_agg_fields.clear();
720
 
  inner_refs_list.clear();
 
720
  non_agg_fields.empty();
 
721
  inner_refs_list.empty();
721
722
  return(error);
722
723
}
723
724