~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_union.cc

  • Committer: Monty Taylor
  • Date: 2008-10-02 01:27:37 UTC
  • Revision ID: monty@inaugust.com-20081002012737-3uxmdovii2l14uqe
Removed unused crud.

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= 
178
181
       order=order->next)
179
182
  {
180
183
    (*order->item)->walk(&Item::change_context_processor, 0,
181
 
                         (unsigned char*) &fake_select_lex->context);
 
184
                         (uchar*) &fake_select_lex->context);
182
185
  }
183
186
}
184
187
 
185
188
 
186
 
bool st_select_lex_unit::prepare(Session *session_arg, select_result *sel_result,
 
189
bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
187
190
                                 uint32_t additional_options)
188
191
{
189
 
  SELECT_LEX *lex_select_save= session_arg->lex->current_select;
 
192
  SELECT_LEX *lex_select_save= thd_arg->lex->current_select;
190
193
  SELECT_LEX *sl, *first_sl= first_select();
191
194
  select_result *tmp_result;
192
195
  bool is_union_select;
223
226
  prepared= 1;
224
227
  saved_error= false;
225
228
  
226
 
  session_arg->lex->current_select= sl= first_sl;
 
229
  thd_arg->lex->current_select= sl= first_sl;
227
230
  found_rows_for_union= first_sl->options & OPTION_FOUND_ROWS;
228
231
  is_union_select= is_union() || fake_select_lex;
229
232
 
245
248
  {
246
249
    bool can_skip_order_by;
247
250
    sl->options|=  SELECT_NO_UNLOCK;
248
 
    JOIN *join= new JOIN(session_arg, sl->item_list, 
249
 
                         sl->options | session_arg->options | additional_options,
 
251
    JOIN *join= new JOIN(thd_arg, sl->item_list, 
 
252
                         sl->options | thd_arg->options | additional_options,
250
253
                         tmp_result);
251
254
    /*
252
255
      setup_tables_done_option should be set only for very first SELECT,
258
261
    if (!join)
259
262
      goto err;
260
263
 
261
 
    session_arg->lex->current_select= sl;
 
264
    thd_arg->lex->current_select= sl;
262
265
 
263
266
    can_skip_order_by= is_union_select && !(sl->braces && sl->explicit_limit);
264
267
 
274
277
                               (order_st*) sl->group_list.first,
275
278
                               sl->having,
276
279
                               (is_union_select ? (order_st*) 0 :
277
 
                                (order_st*) session_arg->lex->proc_list.first),
 
280
                                (order_st*) thd_arg->lex->proc_list.first),
278
281
                               sl, this);
279
282
    /* There are no * in the statement anymore (for PS) */
280
283
    sl->with_wild= 0;
281
284
 
282
 
    if (saved_error || (saved_error= session_arg->is_fatal_error))
 
285
    if (saved_error || (saved_error= thd_arg->is_fatal_error))
283
286
      goto err;
284
287
    /*
285
288
      Use items list of underlaid select for derived tables to preserve
296
299
        field object without table.
297
300
      */
298
301
      assert(!empty_table);
299
 
      empty_table= (Table*) session->calloc(sizeof(Table));
 
302
      empty_table= (Table*) thd->calloc(sizeof(Table));
300
303
      types.empty();
301
304
      List_iterator_fast<Item> it(sl->item_list);
302
305
      Item *item_tmp;
303
306
      while ((item_tmp= it++))
304
307
      {
305
308
        /* Error's in 'new' will be detected after loop */
306
 
        types.push_back(new Item_type_holder(session_arg, item_tmp));
 
309
        types.push_back(new Item_type_holder(thd_arg, item_tmp));
307
310
      }
308
311
 
309
 
      if (session_arg->is_fatal_error)
 
312
      if (thd_arg->is_fatal_error)
310
313
        goto err; // out of memory
311
314
    }
312
315
    else
322
325
      Item *type, *item_tmp;
323
326
      while ((type= tp++, item_tmp= it++))
324
327
      {
325
 
        if (((Item_type_holder*)type)->join_types(session_arg, item_tmp))
 
328
        if (((Item_type_holder*)type)->join_types(thd_arg, item_tmp))
326
329
          return(true);
327
330
      }
328
331
    }
348
351
      }
349
352
    }
350
353
    
351
 
    create_options= (first_sl->options | session_arg->options |
 
354
    create_options= (first_sl->options | thd_arg->options |
352
355
                     TMP_TABLE_ALL_COLUMNS);
353
356
 
354
 
    if (union_result->create_result_table(session, &types, test(union_distinct),
 
357
    if (union_result->create_result_table(thd, &types, test(union_distinct),
355
358
                                          create_options, "", false))
356
359
      goto err;
357
360
    memset(&result_table_list, 0, sizeof(result_table_list));
359
362
    result_table_list.table_name= result_table_list.alias= (char*) "union";
360
363
    result_table_list.table= table= union_result->table;
361
364
 
362
 
    session_arg->lex->current_select= lex_select_save;
 
365
    thd_arg->lex->current_select= lex_select_save;
363
366
    if (!item_list.elements)
364
367
    {
365
368
      saved_error= table->fill_item_list(&item_list);
376
379
    }
377
380
  }
378
381
 
379
 
  session_arg->lex->current_select= lex_select_save;
 
382
  thd_arg->lex->current_select= lex_select_save;
380
383
 
381
 
  return(saved_error || session_arg->is_fatal_error);
 
384
  return(saved_error || thd_arg->is_fatal_error);
382
385
 
383
386
err:
384
 
  session_arg->lex->current_select= lex_select_save;
 
387
  thd_arg->lex->current_select= lex_select_save;
385
388
  return(true);
386
389
}
387
390
 
388
391
 
389
392
bool st_select_lex_unit::exec()
390
393
{
391
 
  SELECT_LEX *lex_select_save= session->lex->current_select;
 
394
  SELECT_LEX *lex_select_save= thd->lex->current_select;
392
395
  SELECT_LEX *select_cursor=first_select();
393
396
  uint64_t add_rows=0;
394
397
  ha_rows examined_rows= 0;
418
421
    for (SELECT_LEX *sl= select_cursor; sl; sl= sl->next_select())
419
422
    {
420
423
      ha_rows records_at_start= 0;
421
 
      session->lex->current_select= sl;
 
424
      thd->lex->current_select= sl;
422
425
 
423
426
      if (optimized)
424
427
        saved_error= sl->join->reinit();
468
471
                                    0);
469
472
        if (!saved_error)
470
473
        {
471
 
          examined_rows+= session->examined_row_count;
 
474
          examined_rows+= thd->examined_row_count;
472
475
          if (union_result->flush())
473
476
          {
474
 
            session->lex->current_select= lex_select_save;
 
477
            thd->lex->current_select= lex_select_save;
475
478
            return(1);
476
479
          }
477
480
        }
478
481
      }
479
482
      if (saved_error)
480
483
      {
481
 
        session->lex->current_select= lex_select_save;
 
484
        thd->lex->current_select= lex_select_save;
482
485
        return(saved_error);
483
486
      }
484
487
      /* Needed for the following test and for records_at_start in next loop */
497
500
          We get this from the difference of between total number of possible
498
501
          rows and actual rows added to the temporary table.
499
502
        */
500
 
        add_rows+= (uint64_t) (session->limit_found_rows - (uint64_t)
 
503
        add_rows+= (uint64_t) (thd->limit_found_rows - (uint64_t)
501
504
                              ((table->file->stats.records -  records_at_start)));
502
505
      }
503
506
    }
507
510
  /* Send result to 'result' */
508
511
  saved_error= true;
509
512
  {
510
 
    if (!session->is_fatal_error)                               // Check if EOM
 
513
    if (!thd->is_fatal_error)                           // Check if EOM
511
514
    {
512
515
      set_limit(global_parameters);
513
 
      init_prepare_fake_select_lex(session);
 
516
      init_prepare_fake_select_lex(thd);
514
517
      JOIN *join= fake_select_lex->join;
515
518
      if (!join)
516
519
      {
522
525
          don't let it allocate the join. Perhaps this is because we need
523
526
          some special parameter values passed to join constructor?
524
527
        */
525
 
        if (!(fake_select_lex->join= new JOIN(session, item_list,
 
528
        if (!(fake_select_lex->join= new JOIN(thd, item_list,
526
529
                                              fake_select_lex->options, result)))
527
530
        {
528
531
          fake_select_lex->table_list.empty();
535
538
          allocation.
536
539
        */
537
540
        fake_select_lex->item_list= item_list;
538
 
        saved_error= mysql_select(session, &fake_select_lex->ref_pointer_array,
 
541
        saved_error= mysql_select(thd, &fake_select_lex->ref_pointer_array,
539
542
                              &result_table_list,
540
543
                              0, item_list, NULL,
541
544
                              global_parameters->order_list.elements,
557
560
            subquery execution rather than EXPLAIN line production. In order 
558
561
            to reset them back, we re-do all of the actions (yes it is ugly):
559
562
          */
560
 
          join->init(session, item_list, fake_select_lex->options, result);
561
 
          saved_error= mysql_select(session, &fake_select_lex->ref_pointer_array,
 
563
          join->init(thd, item_list, fake_select_lex->options, result);
 
564
          saved_error= mysql_select(thd, &fake_select_lex->ref_pointer_array,
562
565
                                &result_table_list,
563
566
                                0, item_list, NULL,
564
567
                                global_parameters->order_list.elements,
578
581
      fake_select_lex->table_list.empty();
579
582
      if (!saved_error)
580
583
      {
581
 
        session->limit_found_rows = (uint64_t)table->file->stats.records + add_rows;
582
 
        session->examined_row_count+= examined_rows;
 
584
        thd->limit_found_rows = (uint64_t)table->file->stats.records + add_rows;
 
585
        thd->examined_row_count+= examined_rows;
583
586
      }
584
587
      /*
585
588
        Mark for slow query log if any of the union parts didn't use
587
590
      */
588
591
    }
589
592
  }
590
 
  session->lex->current_select= lex_select_save;
 
593
  thd->lex->current_select= lex_select_save;
591
594
  return(saved_error);
592
595
}
593
596
 
607
610
    delete union_result;
608
611
    union_result=0; // Safety
609
612
    if (table)
610
 
      table->free_tmp_table(session);
 
613
      table->free_tmp_table(thd);
611
614
    table= 0; // Safety
612
615
  }
613
616