~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to server/sql_union.cc

  • Committer: Monty Taylor
  • Date: 2008-07-26 16:22:28 UTC
  • mto: (236.1.42 codestyle)
  • mto: This revision was merged to the branch mainline in revision 261.
  • Revision ID: monty@inaugust.com-20080726162228-atatk41l6w4np70m
Added gettext calls in to my_getopt.c and drizzle.c

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
18
  UNION  of select's
18
19
  UNION's  were introduced by Monty and Sinisa <sinisa@mysql.com>
19
20
*/
20
 
#include "config.h"
21
 
#include <drizzled/sql_select.h>
22
 
#include <drizzled/error.h>
23
 
#include <drizzled/item/type_holder.h>
24
 
#include <drizzled/sql_base.h>
25
 
#include <drizzled/sql_union.h>
26
 
 
27
 
namespace drizzled
28
 
{
29
 
 
30
 
bool drizzle_union(Session *session, LEX *, select_result *result,
31
 
                   Select_Lex_Unit *unit, uint64_t setup_tables_done_option)
 
21
 
 
22
 
 
23
#include "mysql_priv.h"
 
24
#include "sql_select.h"
 
25
 
 
26
bool mysql_union(THD *thd,
 
27
                 LEX *lex __attribute__((__unused__)),
 
28
                 select_result *result,
 
29
                 SELECT_LEX_UNIT *unit, ulong setup_tables_done_option)
32
30
{
33
31
  bool res;
34
 
  if (!(res= unit->prepare(session, result, SELECT_NO_UNLOCK |
 
32
  if (!(res= unit->prepare(thd, result, SELECT_NO_UNLOCK |
35
33
                           setup_tables_done_option)))
36
34
    res= unit->exec();
37
35
  if (res)
44
42
** store records in temporary table for UNION
45
43
***************************************************************************/
46
44
 
47
 
int select_union::prepare(List<Item> &, Select_Lex_Unit *u)
 
45
int select_union::prepare(List<Item> &list __attribute__((__unused__)),
 
46
                          SELECT_LEX_UNIT *u)
48
47
{
49
48
  unit= u;
50
49
  return 0;
59
58
    unit->offset_limit_cnt--;
60
59
    return 0;
61
60
  }
62
 
  fill_record(session, table->getFields(), values, true);
63
 
  if (session->is_error())
 
61
  fill_record(thd, table->field, values, 1);
 
62
  if (thd->is_error())
64
63
    return 1;
65
64
 
66
 
  if ((error= table->cursor->insertRecord(table->getInsertRecord())))
 
65
  if ((error= table->file->ha_write_row(table->record[0])))
67
66
  {
68
67
    /* create_myisam_from_heap will generate error if needed */
69
 
    if (table->cursor->is_fatal_error(error, HA_CHECK_DUP))
70
 
    {
71
 
      my_error(ER_USE_SQL_BIG_RESULT, MYF(0));
72
 
      return true;
73
 
    }
 
68
    if (table->file->is_fatal_error(error, HA_CHECK_DUP) &&
 
69
        create_myisam_from_heap(thd, table, tmp_table_param.start_recinfo, 
 
70
                                &tmp_table_param.recinfo, error, 1))
 
71
      return 1;
74
72
  }
75
73
  return 0;
76
74
}
85
83
bool select_union::flush()
86
84
{
87
85
  int error;
88
 
  if ((error=table->cursor->extra(HA_EXTRA_NO_CACHE)))
 
86
  if ((error=table->file->extra(HA_EXTRA_NO_CACHE)))
89
87
  {
90
 
    table->print_error(error, MYF(0));
 
88
    table->file->print_error(error, MYF(0));
91
89
    return 1;
92
90
  }
93
91
  return 0;
98
96
 
99
97
  SYNOPSIS
100
98
    select_union::create_result_table()
101
 
      session                thread handle
 
99
      thd                thread handle
102
100
      column_types       a list of items used to define columns of the
103
101
                         temporary table
104
102
      is_union_distinct  if set, the temporary table will eliminate
105
103
                         duplicates on insert
106
104
      options            create options
107
105
      table_alias        name of the temporary table
 
106
      bit_fields_as_long convert bit fields to uint64_t
108
107
 
109
108
  DESCRIPTION
110
109
    Create a temporary table that is used to store the result of a UNION,
116
115
*/
117
116
 
118
117
bool
119
 
select_union::create_result_table(Session *session_arg, List<Item> *column_types,
 
118
select_union::create_result_table(THD *thd_arg, List<Item> *column_types,
120
119
                                  bool is_union_distinct, uint64_t options,
121
 
                                  const char *table_alias)
 
120
                                  const char *table_alias,
 
121
                                  bool bit_fields_as_long)
122
122
{
123
 
  assert(table == NULL);
 
123
  assert(table == 0);
124
124
  tmp_table_param.init();
125
125
  tmp_table_param.field_count= column_types->elements;
 
126
  tmp_table_param.bit_fields_as_long= bit_fields_as_long;
126
127
 
127
 
  if (! (table= create_tmp_table(session_arg, &tmp_table_param, *column_types,
128
 
                                 (Order*) NULL, is_union_distinct, 1,
 
128
  if (! (table= create_tmp_table(thd_arg, &tmp_table_param, *column_types,
 
129
                                 (ORDER*) 0, is_union_distinct, 1,
129
130
                                 options, HA_POS_ERROR, (char*) table_alias)))
130
 
  {
131
131
    return true;
132
 
  }
133
 
 
134
 
  table->cursor->extra(HA_EXTRA_WRITE_CACHE);
135
 
  table->cursor->extra(HA_EXTRA_IGNORE_DUP_KEY);
136
 
 
 
132
  table->file->extra(HA_EXTRA_WRITE_CACHE);
 
133
  table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
137
134
  return false;
138
135
}
139
136
 
147
144
 
148
145
void select_union::cleanup()
149
146
{
150
 
  table->cursor->extra(HA_EXTRA_RESET_STATE);
151
 
  table->cursor->ha_delete_all_rows();
152
 
  table->free_io_cache();
153
 
  table->filesort_free_buffers();
 
147
  table->file->extra(HA_EXTRA_RESET_STATE);
 
148
  table->file->ha_delete_all_rows();
 
149
  free_io_cache(table);
 
150
  filesort_free_buffers(table,0);
154
151
}
155
152
 
156
153
 
158
155
  initialization procedures before fake_select_lex preparation()
159
156
 
160
157
  SYNOPSIS
161
 
    Select_Lex_Unit::init_prepare_fake_select_lex()
162
 
    session             - thread handler
 
158
    st_select_lex_unit::init_prepare_fake_select_lex()
 
159
    thd         - thread handler
163
160
 
164
161
  RETURN
165
162
    options of SELECT
166
163
*/
167
164
 
168
165
void
169
 
Select_Lex_Unit::init_prepare_fake_select_lex(Session *session_arg)
 
166
st_select_lex_unit::init_prepare_fake_select_lex(THD *thd_arg) 
170
167
{
171
 
  session_arg->lex->current_select= fake_select_lex;
172
 
  fake_select_lex->table_list.link_in_list((unsigned char *)&result_table_list,
173
 
                                           (unsigned char **)
 
168
  thd_arg->lex->current_select= fake_select_lex;
 
169
  fake_select_lex->table_list.link_in_list((uchar *)&result_table_list,
 
170
                                           (uchar **)
174
171
                                           &result_table_list.next_local);
175
 
  fake_select_lex->context.table_list=
176
 
    fake_select_lex->context.first_name_resolution_table=
 
172
  fake_select_lex->context.table_list= 
 
173
    fake_select_lex->context.first_name_resolution_table= 
177
174
    fake_select_lex->get_table_list();
178
 
 
179
 
  for (Order *order= (Order *) global_parameters->order_list.first;
180
 
       order;
181
 
       order= order->next)
182
 
    order->item= &order->item_ptr;
183
 
 
184
 
  for (Order *order= (Order *)global_parameters->order_list.first;
 
175
  if (!fake_select_lex->first_execution)
 
176
  {
 
177
    for (ORDER *order= (ORDER *) global_parameters->order_list.first;
 
178
         order;
 
179
         order= order->next)
 
180
      order->item= &order->item_ptr;
 
181
  }
 
182
  for (ORDER *order= (ORDER *)global_parameters->order_list.first;
185
183
       order;
186
184
       order=order->next)
187
185
  {
188
186
    (*order->item)->walk(&Item::change_context_processor, 0,
189
 
                         (unsigned char*) &fake_select_lex->context);
 
187
                         (uchar*) &fake_select_lex->context);
190
188
  }
191
189
}
192
190
 
193
191
 
194
 
bool Select_Lex_Unit::prepare(Session *session_arg, select_result *sel_result,
195
 
                              uint64_t additional_options)
 
192
bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
 
193
                                 uint32_t additional_options)
196
194
{
197
 
  Select_Lex *lex_select_save= session_arg->lex->current_select;
198
 
  Select_Lex *sl, *first_sl= first_select();
 
195
  SELECT_LEX *lex_select_save= thd_arg->lex->current_select;
 
196
  SELECT_LEX *sl, *first_sl= first_select();
199
197
  select_result *tmp_result;
200
198
  bool is_union_select;
201
 
  Table *empty_table= 0;
 
199
  TABLE *empty_table= 0;
202
200
 
203
201
  describe= test(additional_options & SELECT_DESCRIBE);
204
202
 
230
228
  }
231
229
  prepared= 1;
232
230
  saved_error= false;
233
 
 
234
 
  session_arg->lex->current_select= sl= first_sl;
 
231
  
 
232
  thd_arg->lex->current_select= sl= first_sl;
235
233
  found_rows_for_union= first_sl->options & OPTION_FOUND_ROWS;
236
234
  is_union_select= is_union() || fake_select_lex;
237
235
 
253
251
  {
254
252
    bool can_skip_order_by;
255
253
    sl->options|=  SELECT_NO_UNLOCK;
256
 
    Join *join= new Join(session_arg, sl->item_list,
257
 
                         sl->options | session_arg->options | additional_options,
 
254
    JOIN *join= new JOIN(thd_arg, sl->item_list, 
 
255
                         sl->options | thd_arg->options | additional_options,
258
256
                         tmp_result);
259
257
    /*
260
258
      setup_tables_done_option should be set only for very first SELECT,
266
264
    if (!join)
267
265
      goto err;
268
266
 
269
 
    session_arg->lex->current_select= sl;
 
267
    thd_arg->lex->current_select= sl;
270
268
 
271
269
    can_skip_order_by= is_union_select && !(sl->braces && sl->explicit_limit);
272
270
 
273
271
    saved_error= join->prepare(&sl->ref_pointer_array,
274
 
                               (TableList*) sl->table_list.first,
 
272
                               (TABLE_LIST*) sl->table_list.first,
275
273
                               sl->with_wild,
276
274
                               sl->where,
277
275
                               (can_skip_order_by ? 0 :
278
276
                                sl->order_list.elements) +
279
277
                               sl->group_list.elements,
280
278
                               can_skip_order_by ?
281
 
                               (Order*) NULL : (Order *)sl->order_list.first,
282
 
                               (Order*) sl->group_list.first,
 
279
                               (ORDER*) 0 : (ORDER *)sl->order_list.first,
 
280
                               (ORDER*) sl->group_list.first,
283
281
                               sl->having,
 
282
                               (is_union_select ? (ORDER*) 0 :
 
283
                                (ORDER*) thd_arg->lex->proc_list.first),
284
284
                               sl, this);
285
285
    /* There are no * in the statement anymore (for PS) */
286
286
    sl->with_wild= 0;
287
287
 
288
 
    if (saved_error || (saved_error= session_arg->is_fatal_error))
 
288
    if (saved_error || (saved_error= thd_arg->is_fatal_error))
289
289
      goto err;
290
290
    /*
291
291
      Use items list of underlaid select for derived tables to preserve
302
302
        field object without table.
303
303
      */
304
304
      assert(!empty_table);
305
 
      empty_table= (Table*) session->calloc(sizeof(Table));
 
305
      empty_table= (TABLE*) thd->calloc(sizeof(TABLE));
306
306
      types.empty();
307
307
      List_iterator_fast<Item> it(sl->item_list);
308
308
      Item *item_tmp;
309
309
      while ((item_tmp= it++))
310
310
      {
311
311
        /* Error's in 'new' will be detected after loop */
312
 
        types.push_back(new Item_type_holder(session_arg, item_tmp));
 
312
        types.push_back(new Item_type_holder(thd_arg, item_tmp));
313
313
      }
314
314
 
315
 
      if (session_arg->is_fatal_error)
 
315
      if (thd_arg->is_fatal_error)
316
316
        goto err; // out of memory
317
317
    }
318
318
    else
324
324
        goto err;
325
325
      }
326
326
      List_iterator_fast<Item> it(sl->item_list);
327
 
      List_iterator_fast<Item> tp(types);
 
327
      List_iterator_fast<Item> tp(types);       
328
328
      Item *type, *item_tmp;
329
329
      while ((type= tp++, item_tmp= it++))
330
330
      {
331
 
        if (((Item_type_holder*)type)->join_types(session_arg, item_tmp))
 
331
        if (((Item_type_holder*)type)->join_types(thd_arg, item_tmp))
332
332
          return(true);
333
333
      }
334
334
    }
353
353
        goto err;
354
354
      }
355
355
    }
356
 
 
357
 
    create_options= (first_sl->options | session_arg->options |
 
356
    
 
357
    create_options= (first_sl->options | thd_arg->options |
358
358
                     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(thd, &types, test(union_distinct),
 
361
                                          create_options, "", false))
362
362
      goto err;
363
 
    memset(&result_table_list, 0, sizeof(result_table_list));
364
 
    result_table_list.setSchemaName((char*) "");
365
 
    result_table_list.alias= "union";
366
 
    result_table_list.setTableName((char *) "union");
 
363
    bzero((char*) &result_table_list, sizeof(result_table_list));
 
364
    result_table_list.db= (char*) "";
 
365
    result_table_list.table_name= result_table_list.alias= (char*) "union";
367
366
    result_table_list.table= table= union_result->table;
368
367
 
369
 
    session_arg->lex->current_select= lex_select_save;
 
368
    thd_arg->lex->current_select= lex_select_save;
370
369
    if (!item_list.elements)
371
370
    {
372
371
      saved_error= table->fill_item_list(&item_list);
375
374
    }
376
375
    else
377
376
    {
 
377
      assert(thd->stmt_arena->is_conventional() == false);
378
378
      /*
379
379
        We're in execution of a prepared statement or stored procedure:
380
380
        reset field items to point at fields from the created temporary table.
381
381
      */
382
 
      assert(1);
 
382
      table->reset_item_list(&item_list);
383
383
    }
384
384
  }
385
385
 
386
 
  session_arg->lex->current_select= lex_select_save;
 
386
  thd_arg->lex->current_select= lex_select_save;
387
387
 
388
 
  return(saved_error || session_arg->is_fatal_error);
 
388
  return(saved_error || thd_arg->is_fatal_error);
389
389
 
390
390
err:
391
 
  session_arg->lex->current_select= lex_select_save;
 
391
  thd_arg->lex->current_select= lex_select_save;
392
392
  return(true);
393
393
}
394
394
 
395
395
 
396
 
bool Select_Lex_Unit::exec()
 
396
bool st_select_lex_unit::exec()
397
397
{
398
 
  Select_Lex *lex_select_save= session->lex->current_select;
399
 
  Select_Lex *select_cursor=first_select();
 
398
  SELECT_LEX *lex_select_save= thd->lex->current_select;
 
399
  SELECT_LEX *select_cursor=first_select();
400
400
  uint64_t add_rows=0;
401
401
  ha_rows examined_rows= 0;
402
402
 
403
 
  if (executed && uncacheable.none() && ! describe)
404
 
    return false;
 
403
  if (executed && !uncacheable && !describe)
 
404
    return(false);
405
405
  executed= 1;
406
 
 
407
 
  if (uncacheable.any() || ! item || ! item->assigned() || describe)
 
406
  
 
407
  if (uncacheable || !item || !item->assigned() || describe)
408
408
  {
409
409
    if (item)
410
410
      item->reset_value_registration();
414
414
      {
415
415
        item->assigned(0); // We will reinit & rexecute unit
416
416
        item->reset();
417
 
        table->cursor->ha_delete_all_rows();
 
417
        table->file->ha_delete_all_rows();
418
418
      }
419
419
      /* re-enabling indexes for next subselect iteration */
420
 
      if (union_distinct && table->cursor->ha_enable_indexes(HA_KEY_SWITCH_ALL))
 
420
      if (union_distinct && table->file->ha_enable_indexes(HA_KEY_SWITCH_ALL))
421
421
      {
422
422
        assert(0);
423
423
      }
424
424
    }
425
 
    for (Select_Lex *sl= select_cursor; sl; sl= sl->next_select())
 
425
    for (SELECT_LEX *sl= select_cursor; sl; sl= sl->next_select())
426
426
    {
427
427
      ha_rows records_at_start= 0;
428
 
      session->lex->current_select= sl;
 
428
      thd->lex->current_select= sl;
429
429
 
430
430
      if (optimized)
431
431
        saved_error= sl->join->reinit();
448
448
          we don't calculate found_rows() per union part.
449
449
          Otherwise, SQL_CALC_FOUND_ROWS should be done on all sub parts.
450
450
        */
451
 
        sl->join->select_options=
 
451
        sl->join->select_options= 
452
452
          (select_limit_cnt == HA_POS_ERROR || sl->braces) ?
453
453
          sl->options & ~OPTION_FOUND_ROWS : sl->options | found_rows_for_union;
454
454
 
 
455
        /* dump_TABLE_LIST_struct(select_lex, select_lex->leaf_tables); */
 
456
        if (sl->join->flatten_subqueries())
 
457
          return(true);
 
458
 
 
459
        /* dump_TABLE_LIST_struct(select_lex, select_lex->leaf_tables); */
455
460
        saved_error= sl->join->optimize();
456
461
      }
457
462
      if (!saved_error)
458
463
      {
459
 
        records_at_start= table->cursor->stats.records;
 
464
        records_at_start= table->file->stats.records;
460
465
        sl->join->exec();
461
466
        if (sl == union_distinct)
462
467
        {
463
 
          if (table->cursor->ha_disable_indexes(HA_KEY_SWITCH_ALL))
 
468
          if (table->file->ha_disable_indexes(HA_KEY_SWITCH_ALL))
464
469
            return(true);
465
470
          table->no_keyread=1;
466
471
        }
470
475
                                    0);
471
476
        if (!saved_error)
472
477
        {
473
 
          examined_rows+= session->examined_row_count;
 
478
          examined_rows+= thd->examined_row_count;
474
479
          if (union_result->flush())
475
480
          {
476
 
            session->lex->current_select= lex_select_save;
 
481
            thd->lex->current_select= lex_select_save;
477
482
            return(1);
478
483
          }
479
484
        }
480
485
      }
481
486
      if (saved_error)
482
487
      {
483
 
        session->lex->current_select= lex_select_save;
 
488
        thd->lex->current_select= lex_select_save;
484
489
        return(saved_error);
485
490
      }
486
491
      /* Needed for the following test and for records_at_start in next loop */
487
 
      int error= table->cursor->info(HA_STATUS_VARIABLE);
488
 
      if (error)
 
492
      int error= table->file->info(HA_STATUS_VARIABLE);
 
493
      if(error)
489
494
      {
490
 
        table->print_error(error, MYF(0));
 
495
        table->file->print_error(error, MYF(0));
491
496
        return(1);
492
497
      }
493
 
      if (found_rows_for_union && !sl->braces &&
 
498
      if (found_rows_for_union && !sl->braces && 
494
499
          select_limit_cnt != HA_POS_ERROR)
495
500
      {
496
501
        /*
499
504
          We get this from the difference of between total number of possible
500
505
          rows and actual rows added to the temporary table.
501
506
        */
502
 
        add_rows+= (uint64_t) (session->limit_found_rows - (uint64_t)
503
 
                              ((table->cursor->stats.records -  records_at_start)));
 
507
        add_rows+= (uint64_t) (thd->limit_found_rows - (uint64_t)
 
508
                              ((table->file->stats.records -  records_at_start)));
504
509
      }
505
510
    }
506
511
  }
509
514
  /* Send result to 'result' */
510
515
  saved_error= true;
511
516
  {
512
 
    if (!session->is_fatal_error)                               // Check if EOM
 
517
    if (!thd->is_fatal_error)                           // Check if EOM
513
518
    {
514
519
      set_limit(global_parameters);
515
 
      init_prepare_fake_select_lex(session);
516
 
      Join *join= fake_select_lex->join;
 
520
      init_prepare_fake_select_lex(thd);
 
521
      JOIN *join= fake_select_lex->join;
517
522
      if (!join)
518
523
      {
519
524
        /*
520
525
          allocate JOIN for fake select only once (prevent
521
 
          select_query automatic allocation)
522
 
          TODO: The above is nonsense. select_query() will not allocate the
 
526
          mysql_select automatic allocation)
 
527
          TODO: The above is nonsense. mysql_select() will not allocate the
523
528
          join if one already exists. There must be some other reason why we
524
529
          don't let it allocate the join. Perhaps this is because we need
525
530
          some special parameter values passed to join constructor?
526
531
        */
527
 
        if (!(fake_select_lex->join= new Join(session, item_list,
 
532
        if (!(fake_select_lex->join= new JOIN(thd, item_list,
528
533
                                              fake_select_lex->options, result)))
529
534
        {
530
535
          fake_select_lex->table_list.empty();
533
538
        fake_select_lex->join->no_const_tables= true;
534
539
 
535
540
        /*
536
 
          Fake Select_Lex should have item list for correctref_array
 
541
          Fake st_select_lex should have item list for correctref_array
537
542
          allocation.
538
543
        */
539
544
        fake_select_lex->item_list= item_list;
540
 
        saved_error= select_query(session, &fake_select_lex->ref_pointer_array,
 
545
        saved_error= mysql_select(thd, &fake_select_lex->ref_pointer_array,
541
546
                              &result_table_list,
542
547
                              0, item_list, NULL,
543
548
                              global_parameters->order_list.elements,
544
 
                              (Order*)global_parameters->order_list.first,
545
 
                              (Order*) NULL, NULL,
 
549
                              (ORDER*)global_parameters->order_list.first,
 
550
                              (ORDER*) NULL, NULL, (ORDER*) NULL,
546
551
                              fake_select_lex->options | SELECT_NO_UNLOCK,
547
552
                              result, this, fake_select_lex);
548
553
      }
556
561
             - 1st time is a real evaluation to get the subquery value
557
562
             - 2nd time is to produce EXPLAIN output rows.
558
563
            1st execution sets certain members (e.g. select_result) to perform
559
 
            subquery execution rather than EXPLAIN line production. In order
 
564
            subquery execution rather than EXPLAIN line production. In order 
560
565
            to reset them back, we re-do all of the actions (yes it is ugly):
561
566
          */
562
 
                join->reset(session, item_list, fake_select_lex->options, result);
563
 
          saved_error= select_query(session, &fake_select_lex->ref_pointer_array,
 
567
          join->init(thd, item_list, fake_select_lex->options, result);
 
568
          saved_error= mysql_select(thd, &fake_select_lex->ref_pointer_array,
564
569
                                &result_table_list,
565
570
                                0, item_list, NULL,
566
571
                                global_parameters->order_list.elements,
567
 
                                (Order*)global_parameters->order_list.first,
568
 
                                (Order*) NULL, NULL,
 
572
                                (ORDER*)global_parameters->order_list.first,
 
573
                                (ORDER*) NULL, NULL, (ORDER*) NULL,
569
574
                                fake_select_lex->options | SELECT_NO_UNLOCK,
570
575
                                result, this, fake_select_lex);
571
576
        }
580
585
      fake_select_lex->table_list.empty();
581
586
      if (!saved_error)
582
587
      {
583
 
        session->limit_found_rows = (uint64_t)table->cursor->stats.records + add_rows;
584
 
        session->examined_row_count+= examined_rows;
 
588
        thd->limit_found_rows = (uint64_t)table->file->stats.records + add_rows;
 
589
        thd->examined_row_count+= examined_rows;
585
590
      }
586
591
      /*
587
592
        Mark for slow query log if any of the union parts didn't use
589
594
      */
590
595
    }
591
596
  }
592
 
  session->lex->current_select= lex_select_save;
 
597
  thd->lex->current_select= lex_select_save;
593
598
  return(saved_error);
594
599
}
595
600
 
596
601
 
597
 
bool Select_Lex_Unit::cleanup()
 
602
bool st_select_lex_unit::cleanup()
598
603
{
599
604
  int error= 0;
600
605
 
608
613
  {
609
614
    delete union_result;
610
615
    union_result=0; // Safety
 
616
    if (table)
 
617
      free_tmp_table(thd, table);
611
618
    table= 0; // Safety
612
619
  }
613
620
 
614
 
  for (Select_Lex *sl= first_select(); sl; sl= sl->next_select())
 
621
  for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select())
615
622
    error|= sl->cleanup();
616
623
 
617
624
  if (fake_select_lex)
618
625
  {
619
 
    Join *join;
 
626
    JOIN *join;
620
627
    if ((join= fake_select_lex->join))
621
628
    {
622
629
      join->tables_list= 0;
625
632
    error|= fake_select_lex->cleanup();
626
633
    if (fake_select_lex->order_list.elements)
627
634
    {
628
 
      Order *ord;
629
 
      for (ord= (Order*)fake_select_lex->order_list.first; ord; ord= ord->next)
 
635
      ORDER *ord;
 
636
      for (ord= (ORDER*)fake_select_lex->order_list.first; ord; ord= ord->next)
630
637
        (*ord->item)->cleanup();
631
638
    }
632
639
  }
635
642
}
636
643
 
637
644
 
638
 
void Select_Lex_Unit::reinit_exec_mechanism()
 
645
void st_select_lex_unit::reinit_exec_mechanism()
639
646
{
640
647
  prepared= optimized= executed= 0;
641
648
}
645
652
  change select_result object of unit
646
653
 
647
654
  SYNOPSIS
648
 
    Select_Lex_Unit::change_result()
 
655
    st_select_lex_unit::change_result()
649
656
    result      new select_result object
650
657
    old_result  old select_result object
651
658
 
654
661
    true  - error
655
662
*/
656
663
 
657
 
bool Select_Lex_Unit::change_result(select_result_interceptor *new_result,
 
664
bool st_select_lex_unit::change_result(select_result_interceptor *new_result,
658
665
                                       select_result_interceptor *old_result)
659
666
{
660
667
  bool res= false;
661
 
  for (Select_Lex *sl= first_select(); sl; sl= sl->next_select())
 
668
  for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select())
662
669
  {
663
670
    if (sl->join && sl->join->result == old_result)
664
671
      if (sl->join->change_result(new_result))
673
680
  Get column type information for this unit.
674
681
 
675
682
  SYNOPSIS
676
 
    Select_Lex_Unit::get_unit_column_types()
 
683
    st_select_lex_unit::get_unit_column_types()
677
684
 
678
685
  DESCRIPTION
679
686
    For a single-select the column types are taken
680
687
    from the list of selected items. For a union this function
681
 
    assumes that Select_Lex_Unit::prepare has been called
 
688
    assumes that st_select_lex_unit::prepare has been called
682
689
    and returns the type holders that were created for unioned
683
690
    column types of all selects.
684
691
 
685
692
  NOTES
686
693
    The implementation of this function should be in sync with
687
 
    Select_Lex_Unit::prepare()
 
694
    st_select_lex_unit::prepare()
688
695
*/
689
696
 
690
 
List<Item> *Select_Lex_Unit::get_unit_column_types()
 
697
List<Item> *st_select_lex_unit::get_unit_column_types()
691
698
{
692
 
  Select_Lex *sl= first_select();
 
699
  SELECT_LEX *sl= first_select();
693
700
 
694
701
  if (is_union())
695
702
  {
701
708
  return &sl->item_list;
702
709
}
703
710
 
704
 
bool Select_Lex::cleanup()
 
711
bool st_select_lex::cleanup()
705
712
{
706
713
  bool error= false;
707
714
 
708
715
  if (join)
709
716
  {
710
 
    assert((Select_Lex*)join->select_lex == this);
 
717
    assert((st_select_lex*)join->select_lex == this);
711
718
    error= join->destroy();
712
719
    delete join;
713
720
    join= 0;
714
721
  }
715
 
  for (Select_Lex_Unit *lex_unit= first_inner_unit(); lex_unit ;
 
722
  for (SELECT_LEX_UNIT *lex_unit= first_inner_unit(); lex_unit ;
716
723
       lex_unit= lex_unit->next_unit())
717
724
  {
718
 
    error= (bool) ((uint32_t) error | (uint32_t) lex_unit->cleanup());
 
725
    error= (bool) ((uint) error | (uint) lex_unit->cleanup());
719
726
  }
720
727
  non_agg_fields.empty();
721
728
  inner_refs_list.empty();
723
730
}
724
731
 
725
732
 
726
 
void Select_Lex::cleanup_all_joins(bool full)
 
733
void st_select_lex::cleanup_all_joins(bool full)
727
734
{
728
 
  Select_Lex_Unit *unit;
729
 
  Select_Lex *sl;
 
735
  SELECT_LEX_UNIT *unit;
 
736
  SELECT_LEX *sl;
730
737
 
731
738
  if (join)
732
739
    join->cleanup(full);
735
742
    for (sl= unit->first_select(); sl; sl= sl->next_select())
736
743
      sl->cleanup_all_joins(full);
737
744
}
738
 
 
739
 
} /* namespace drizzled */