~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_union.cc

  • Committer: Monty Taylor
  • Date: 2008-09-16 00:00:48 UTC
  • mto: This revision was merged to the branch mainline in revision 391.
  • Revision ID: monty@inaugust.com-20080916000048-3rvrv3gv9l0ad3gs
Fixed copyright headers in drizzled/

Show diffs side-by-side

added added

removed removed

Lines of Context:
19
19
*/
20
20
#include <drizzled/server_includes.h>
21
21
#include <drizzled/sql_select.h>
22
 
#include <drizzled/error.h>
 
22
#include <drizzled/drizzled_error_messages.h>
23
23
 
24
 
bool mysql_union(Session *session, LEX *, select_result *result,
 
24
bool mysql_union(THD *thd,
 
25
                 LEX *lex __attribute__((unused)),
 
26
                 select_result *result,
25
27
                 SELECT_LEX_UNIT *unit, ulong setup_tables_done_option)
26
28
{
27
29
  bool res;
28
 
  if (!(res= unit->prepare(session, result, SELECT_NO_UNLOCK |
 
30
  if (!(res= unit->prepare(thd, result, SELECT_NO_UNLOCK |
29
31
                           setup_tables_done_option)))
30
32
    res= unit->exec();
31
33
  if (res)
38
40
** store records in temporary table for UNION
39
41
***************************************************************************/
40
42
 
41
 
int select_union::prepare(List<Item> &, SELECT_LEX_UNIT *u)
 
43
int select_union::prepare(List<Item> &list __attribute__((unused)),
 
44
                          SELECT_LEX_UNIT *u)
42
45
{
43
46
  unit= u;
44
47
  return 0;
53
56
    unit->offset_limit_cnt--;
54
57
    return 0;
55
58
  }
56
 
  fill_record(session, table->field, values, 1);
57
 
  if (session->is_error())
 
59
  fill_record(thd, table->field, values, 1);
 
60
  if (thd->is_error())
58
61
    return 1;
59
62
 
60
63
  if ((error= table->file->ha_write_row(table->record[0])))
61
64
  {
62
65
    /* create_myisam_from_heap will generate error if needed */
63
66
    if (table->file->is_fatal_error(error, HA_CHECK_DUP) &&
64
 
        create_myisam_from_heap(session, table, tmp_table_param.start_recinfo, 
 
67
        create_myisam_from_heap(thd, table, tmp_table_param.start_recinfo, 
65
68
                                &tmp_table_param.recinfo, error, 1))
66
69
      return 1;
67
70
  }
91
94
 
92
95
  SYNOPSIS
93
96
    select_union::create_result_table()
94
 
      session                thread handle
 
97
      thd                thread handle
95
98
      column_types       a list of items used to define columns of the
96
99
                         temporary table
97
100
      is_union_distinct  if set, the temporary table will eliminate
110
113
*/
111
114
 
112
115
bool
113
 
select_union::create_result_table(Session *session_arg, List<Item> *column_types,
 
116
select_union::create_result_table(THD *thd_arg, List<Item> *column_types,
114
117
                                  bool is_union_distinct, uint64_t options,
115
118
                                  const char *table_alias,
116
119
                                  bool bit_fields_as_long)
120
123
  tmp_table_param.field_count= column_types->elements;
121
124
  tmp_table_param.bit_fields_as_long= bit_fields_as_long;
122
125
 
123
 
  if (! (table= create_tmp_table(session_arg, &tmp_table_param, *column_types,
 
126
  if (! (table= create_tmp_table(thd_arg, &tmp_table_param, *column_types,
124
127
                                 (order_st*) 0, is_union_distinct, 1,
125
128
                                 options, HA_POS_ERROR, (char*) table_alias)))
126
129
    return true;
151
154
 
152
155
  SYNOPSIS
153
156
    st_select_lex_unit::init_prepare_fake_select_lex()
154
 
    session             - thread handler
 
157
    thd         - thread handler
155
158
 
156
159
  RETURN
157
160
    options of SELECT
158
161
*/
159
162
 
160
163
void
161
 
st_select_lex_unit::init_prepare_fake_select_lex(Session *session_arg) 
 
164
st_select_lex_unit::init_prepare_fake_select_lex(THD *thd_arg) 
162
165
{
163
 
  session_arg->lex->current_select= fake_select_lex;
164
 
  fake_select_lex->table_list.link_in_list((unsigned char *)&result_table_list,
165
 
                                           (unsigned char **)
 
166
  thd_arg->lex->current_select= fake_select_lex;
 
167
  fake_select_lex->table_list.link_in_list((uchar *)&result_table_list,
 
168
                                           (uchar **)
166
169
                                           &result_table_list.next_local);
167
170
  fake_select_lex->context.table_list= 
168
171
    fake_select_lex->context.first_name_resolution_table= 
169
172
    fake_select_lex->get_table_list();
170
 
 
171
 
  for (order_st *order= (order_st *) global_parameters->order_list.first;
172
 
       order;
173
 
       order= order->next)
174
 
    order->item= &order->item_ptr;
175
 
 
 
173
  if (!fake_select_lex->first_execution)
 
174
  {
 
175
    for (order_st *order= (order_st *) global_parameters->order_list.first;
 
176
         order;
 
177
         order= order->next)
 
178
      order->item= &order->item_ptr;
 
179
  }
176
180
  for (order_st *order= (order_st *)global_parameters->order_list.first;
177
181
       order;
178
182
       order=order->next)
179
183
  {
180
184
    (*order->item)->walk(&Item::change_context_processor, 0,
181
 
                         (unsigned char*) &fake_select_lex->context);
 
185
                         (uchar*) &fake_select_lex->context);
182
186
  }
183
187
}
184
188
 
185
189
 
186
 
bool st_select_lex_unit::prepare(Session *session_arg, select_result *sel_result,
 
190
bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
187
191
                                 uint32_t additional_options)
188
192
{
189
 
  SELECT_LEX *lex_select_save= session_arg->lex->current_select;
 
193
  SELECT_LEX *lex_select_save= thd_arg->lex->current_select;
190
194
  SELECT_LEX *sl, *first_sl= first_select();
191
195
  select_result *tmp_result;
192
196
  bool is_union_select;
223
227
  prepared= 1;
224
228
  saved_error= false;
225
229
  
226
 
  session_arg->lex->current_select= sl= first_sl;
 
230
  thd_arg->lex->current_select= sl= first_sl;
227
231
  found_rows_for_union= first_sl->options & OPTION_FOUND_ROWS;
228
232
  is_union_select= is_union() || fake_select_lex;
229
233
 
245
249
  {
246
250
    bool can_skip_order_by;
247
251
    sl->options|=  SELECT_NO_UNLOCK;
248
 
    JOIN *join= new JOIN(session_arg, sl->item_list, 
249
 
                         sl->options | session_arg->options | additional_options,
 
252
    JOIN *join= new JOIN(thd_arg, sl->item_list, 
 
253
                         sl->options | thd_arg->options | additional_options,
250
254
                         tmp_result);
251
255
    /*
252
256
      setup_tables_done_option should be set only for very first SELECT,
258
262
    if (!join)
259
263
      goto err;
260
264
 
261
 
    session_arg->lex->current_select= sl;
 
265
    thd_arg->lex->current_select= sl;
262
266
 
263
267
    can_skip_order_by= is_union_select && !(sl->braces && sl->explicit_limit);
264
268
 
274
278
                               (order_st*) sl->group_list.first,
275
279
                               sl->having,
276
280
                               (is_union_select ? (order_st*) 0 :
277
 
                                (order_st*) session_arg->lex->proc_list.first),
 
281
                                (order_st*) thd_arg->lex->proc_list.first),
278
282
                               sl, this);
279
283
    /* There are no * in the statement anymore (for PS) */
280
284
    sl->with_wild= 0;
281
285
 
282
 
    if (saved_error || (saved_error= session_arg->is_fatal_error))
 
286
    if (saved_error || (saved_error= thd_arg->is_fatal_error))
283
287
      goto err;
284
288
    /*
285
289
      Use items list of underlaid select for derived tables to preserve
296
300
        field object without table.
297
301
      */
298
302
      assert(!empty_table);
299
 
      empty_table= (Table*) session->calloc(sizeof(Table));
 
303
      empty_table= (Table*) thd->calloc(sizeof(Table));
300
304
      types.empty();
301
305
      List_iterator_fast<Item> it(sl->item_list);
302
306
      Item *item_tmp;
303
307
      while ((item_tmp= it++))
304
308
      {
305
309
        /* Error's in 'new' will be detected after loop */
306
 
        types.push_back(new Item_type_holder(session_arg, item_tmp));
 
310
        types.push_back(new Item_type_holder(thd_arg, item_tmp));
307
311
      }
308
312
 
309
 
      if (session_arg->is_fatal_error)
 
313
      if (thd_arg->is_fatal_error)
310
314
        goto err; // out of memory
311
315
    }
312
316
    else
322
326
      Item *type, *item_tmp;
323
327
      while ((type= tp++, item_tmp= it++))
324
328
      {
325
 
        if (((Item_type_holder*)type)->join_types(session_arg, item_tmp))
 
329
        if (((Item_type_holder*)type)->join_types(thd_arg, item_tmp))
326
330
          return(true);
327
331
      }
328
332
    }
348
352
      }
349
353
    }
350
354
    
351
 
    create_options= (first_sl->options | session_arg->options |
 
355
    create_options= (first_sl->options | thd_arg->options |
352
356
                     TMP_TABLE_ALL_COLUMNS);
353
357
 
354
 
    if (union_result->create_result_table(session, &types, test(union_distinct),
 
358
    if (union_result->create_result_table(thd, &types, test(union_distinct),
355
359
                                          create_options, "", false))
356
360
      goto err;
357
361
    memset(&result_table_list, 0, sizeof(result_table_list));
359
363
    result_table_list.table_name= result_table_list.alias= (char*) "union";
360
364
    result_table_list.table= table= union_result->table;
361
365
 
362
 
    session_arg->lex->current_select= lex_select_save;
 
366
    thd_arg->lex->current_select= lex_select_save;
363
367
    if (!item_list.elements)
364
368
    {
365
369
      saved_error= table->fill_item_list(&item_list);
368
372
    }
369
373
    else
370
374
    {
 
375
      assert(thd->stmt_arena->is_conventional() == false);
371
376
      /*
372
377
        We're in execution of a prepared statement or stored procedure:
373
378
        reset field items to point at fields from the created temporary table.
374
379
      */
375
 
      assert(1);
 
380
      table->reset_item_list(&item_list);
376
381
    }
377
382
  }
378
383
 
379
 
  session_arg->lex->current_select= lex_select_save;
 
384
  thd_arg->lex->current_select= lex_select_save;
380
385
 
381
 
  return(saved_error || session_arg->is_fatal_error);
 
386
  return(saved_error || thd_arg->is_fatal_error);
382
387
 
383
388
err:
384
 
  session_arg->lex->current_select= lex_select_save;
 
389
  thd_arg->lex->current_select= lex_select_save;
385
390
  return(true);
386
391
}
387
392
 
388
393
 
389
394
bool st_select_lex_unit::exec()
390
395
{
391
 
  SELECT_LEX *lex_select_save= session->lex->current_select;
 
396
  SELECT_LEX *lex_select_save= thd->lex->current_select;
392
397
  SELECT_LEX *select_cursor=first_select();
393
398
  uint64_t add_rows=0;
394
399
  ha_rows examined_rows= 0;
418
423
    for (SELECT_LEX *sl= select_cursor; sl; sl= sl->next_select())
419
424
    {
420
425
      ha_rows records_at_start= 0;
421
 
      session->lex->current_select= sl;
 
426
      thd->lex->current_select= sl;
422
427
 
423
428
      if (optimized)
424
429
        saved_error= sl->join->reinit();
468
473
                                    0);
469
474
        if (!saved_error)
470
475
        {
471
 
          examined_rows+= session->examined_row_count;
 
476
          examined_rows+= thd->examined_row_count;
472
477
          if (union_result->flush())
473
478
          {
474
 
            session->lex->current_select= lex_select_save;
 
479
            thd->lex->current_select= lex_select_save;
475
480
            return(1);
476
481
          }
477
482
        }
478
483
      }
479
484
      if (saved_error)
480
485
      {
481
 
        session->lex->current_select= lex_select_save;
 
486
        thd->lex->current_select= lex_select_save;
482
487
        return(saved_error);
483
488
      }
484
489
      /* Needed for the following test and for records_at_start in next loop */
497
502
          We get this from the difference of between total number of possible
498
503
          rows and actual rows added to the temporary table.
499
504
        */
500
 
        add_rows+= (uint64_t) (session->limit_found_rows - (uint64_t)
 
505
        add_rows+= (uint64_t) (thd->limit_found_rows - (uint64_t)
501
506
                              ((table->file->stats.records -  records_at_start)));
502
507
      }
503
508
    }
507
512
  /* Send result to 'result' */
508
513
  saved_error= true;
509
514
  {
510
 
    if (!session->is_fatal_error)                               // Check if EOM
 
515
    if (!thd->is_fatal_error)                           // Check if EOM
511
516
    {
512
517
      set_limit(global_parameters);
513
 
      init_prepare_fake_select_lex(session);
 
518
      init_prepare_fake_select_lex(thd);
514
519
      JOIN *join= fake_select_lex->join;
515
520
      if (!join)
516
521
      {
522
527
          don't let it allocate the join. Perhaps this is because we need
523
528
          some special parameter values passed to join constructor?
524
529
        */
525
 
        if (!(fake_select_lex->join= new JOIN(session, item_list,
 
530
        if (!(fake_select_lex->join= new JOIN(thd, item_list,
526
531
                                              fake_select_lex->options, result)))
527
532
        {
528
533
          fake_select_lex->table_list.empty();
535
540
          allocation.
536
541
        */
537
542
        fake_select_lex->item_list= item_list;
538
 
        saved_error= mysql_select(session, &fake_select_lex->ref_pointer_array,
 
543
        saved_error= mysql_select(thd, &fake_select_lex->ref_pointer_array,
539
544
                              &result_table_list,
540
545
                              0, item_list, NULL,
541
546
                              global_parameters->order_list.elements,
557
562
            subquery execution rather than EXPLAIN line production. In order 
558
563
            to reset them back, we re-do all of the actions (yes it is ugly):
559
564
          */
560
 
          join->init(session, item_list, fake_select_lex->options, result);
561
 
          saved_error= mysql_select(session, &fake_select_lex->ref_pointer_array,
 
565
          join->init(thd, item_list, fake_select_lex->options, result);
 
566
          saved_error= mysql_select(thd, &fake_select_lex->ref_pointer_array,
562
567
                                &result_table_list,
563
568
                                0, item_list, NULL,
564
569
                                global_parameters->order_list.elements,
578
583
      fake_select_lex->table_list.empty();
579
584
      if (!saved_error)
580
585
      {
581
 
        session->limit_found_rows = (uint64_t)table->file->stats.records + add_rows;
582
 
        session->examined_row_count+= examined_rows;
 
586
        thd->limit_found_rows = (uint64_t)table->file->stats.records + add_rows;
 
587
        thd->examined_row_count+= examined_rows;
583
588
      }
584
589
      /*
585
590
        Mark for slow query log if any of the union parts didn't use
587
592
      */
588
593
    }
589
594
  }
590
 
  session->lex->current_select= lex_select_save;
 
595
  thd->lex->current_select= lex_select_save;
591
596
  return(saved_error);
592
597
}
593
598
 
607
612
    delete union_result;
608
613
    union_result=0; // Safety
609
614
    if (table)
610
 
      table->free_tmp_table(session);
 
615
      table->free_tmp_table(thd);
611
616
    table= 0; // Safety
612
617
  }
613
618