~stewart/drizzle/embedded-innodb-create-select-transaction-arrgh

« back to all changes in this revision

Viewing changes to sql/sql_union.cc

  • Committer: brian
  • Date: 2008-06-25 05:29:13 UTC
  • Revision ID: brian@localhost.localdomain-20080625052913-6upwo0jsrl4lnapl
clean slate

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (C) 2000-2003 MySQL AB
 
2
 
 
3
   This program is free software; you can redistribute it and/or modify
 
4
   it under the terms of the GNU General Public License as published by
 
5
   the Free Software Foundation; version 2 of the License.
 
6
 
 
7
   This program is distributed in the hope that it will be useful,
 
8
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
9
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
10
   GNU General Public License for more details.
 
11
 
 
12
   You should have received a copy of the GNU General Public License
 
13
   along with this program; if not, write to the Free Software
 
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
 
15
 
 
16
 
 
17
/*
 
18
  UNION  of select's
 
19
  UNION's  were introduced by Monty and Sinisa <sinisa@mysql.com>
 
20
*/
 
21
 
 
22
 
 
23
#include "mysql_priv.h"
 
24
#include "sql_select.h"
 
25
 
 
26
bool mysql_union(THD *thd, LEX *lex, select_result *result,
 
27
                 SELECT_LEX_UNIT *unit, ulong setup_tables_done_option)
 
28
{
 
29
  DBUG_ENTER("mysql_union");
 
30
  bool res;
 
31
  if (!(res= unit->prepare(thd, result, SELECT_NO_UNLOCK |
 
32
                           setup_tables_done_option)))
 
33
    res= unit->exec();
 
34
  if (res)
 
35
    res|= unit->cleanup();
 
36
  DBUG_RETURN(res);
 
37
}
 
38
 
 
39
 
 
40
/***************************************************************************
 
41
** store records in temporary table for UNION
 
42
***************************************************************************/
 
43
 
 
44
int select_union::prepare(List<Item> &list, SELECT_LEX_UNIT *u)
 
45
{
 
46
  unit= u;
 
47
  return 0;
 
48
}
 
49
 
 
50
 
 
51
bool select_union::send_data(List<Item> &values)
 
52
{
 
53
  int error= 0;
 
54
  if (unit->offset_limit_cnt)
 
55
  {                                             // using limit offset,count
 
56
    unit->offset_limit_cnt--;
 
57
    return 0;
 
58
  }
 
59
  fill_record(thd, table->field, values, 1);
 
60
  if (thd->is_error())
 
61
    return 1;
 
62
 
 
63
  if ((error= table->file->ha_write_row(table->record[0])))
 
64
  {
 
65
    /* create_myisam_from_heap will generate error if needed */
 
66
    if (table->file->is_fatal_error(error, HA_CHECK_DUP) &&
 
67
        create_myisam_from_heap(thd, table, tmp_table_param.start_recinfo, 
 
68
                                &tmp_table_param.recinfo, error, 1))
 
69
      return 1;
 
70
  }
 
71
  return 0;
 
72
}
 
73
 
 
74
 
 
75
bool select_union::send_eof()
 
76
{
 
77
  return 0;
 
78
}
 
79
 
 
80
 
 
81
bool select_union::flush()
 
82
{
 
83
  int error;
 
84
  if ((error=table->file->extra(HA_EXTRA_NO_CACHE)))
 
85
  {
 
86
    table->file->print_error(error, MYF(0));
 
87
    return 1;
 
88
  }
 
89
  return 0;
 
90
}
 
91
 
 
92
/*
 
93
  Create a temporary table to store the result of select_union.
 
94
 
 
95
  SYNOPSIS
 
96
    select_union::create_result_table()
 
97
      thd                thread handle
 
98
      column_types       a list of items used to define columns of the
 
99
                         temporary table
 
100
      is_union_distinct  if set, the temporary table will eliminate
 
101
                         duplicates on insert
 
102
      options            create options
 
103
      table_alias        name of the temporary table
 
104
      bit_fields_as_long convert bit fields to ulonglong
 
105
 
 
106
  DESCRIPTION
 
107
    Create a temporary table that is used to store the result of a UNION,
 
108
    derived table, or a materialized cursor.
 
109
 
 
110
  RETURN VALUE
 
111
    0                    The table has been created successfully.
 
112
    1                    create_tmp_table failed.
 
113
*/
 
114
 
 
115
bool
 
116
select_union::create_result_table(THD *thd_arg, List<Item> *column_types,
 
117
                                  bool is_union_distinct, ulonglong options,
 
118
                                  const char *table_alias,
 
119
                                  bool bit_fields_as_long)
 
120
{
 
121
  DBUG_ASSERT(table == 0);
 
122
  tmp_table_param.init();
 
123
  tmp_table_param.field_count= column_types->elements;
 
124
  tmp_table_param.bit_fields_as_long= bit_fields_as_long;
 
125
 
 
126
  if (! (table= create_tmp_table(thd_arg, &tmp_table_param, *column_types,
 
127
                                 (ORDER*) 0, is_union_distinct, 1,
 
128
                                 options, HA_POS_ERROR, (char*) table_alias)))
 
129
    return TRUE;
 
130
  table->file->extra(HA_EXTRA_WRITE_CACHE);
 
131
  table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
 
132
  return FALSE;
 
133
}
 
134
 
 
135
 
 
136
/**
 
137
  Reset and empty the temporary table that stores the materialized query result.
 
138
 
 
139
  @note The cleanup performed here is exactly the same as for the two temp
 
140
  tables of JOIN - exec_tmp_table_[1 | 2].
 
141
*/
 
142
 
 
143
void select_union::cleanup()
 
144
{
 
145
  table->file->extra(HA_EXTRA_RESET_STATE);
 
146
  table->file->ha_delete_all_rows();
 
147
  free_io_cache(table);
 
148
  filesort_free_buffers(table,0);
 
149
}
 
150
 
 
151
 
 
152
/*
 
153
  initialization procedures before fake_select_lex preparation()
 
154
 
 
155
  SYNOPSIS
 
156
    st_select_lex_unit::init_prepare_fake_select_lex()
 
157
    thd         - thread handler
 
158
 
 
159
  RETURN
 
160
    options of SELECT
 
161
*/
 
162
 
 
163
void
 
164
st_select_lex_unit::init_prepare_fake_select_lex(THD *thd_arg) 
 
165
{
 
166
  thd_arg->lex->current_select= fake_select_lex;
 
167
  fake_select_lex->table_list.link_in_list((uchar *)&result_table_list,
 
168
                                           (uchar **)
 
169
                                           &result_table_list.next_local);
 
170
  fake_select_lex->context.table_list= 
 
171
    fake_select_lex->context.first_name_resolution_table= 
 
172
    fake_select_lex->get_table_list();
 
173
  if (!fake_select_lex->first_execution)
 
174
  {
 
175
    for (ORDER *order= (ORDER *) global_parameters->order_list.first;
 
176
         order;
 
177
         order= order->next)
 
178
      order->item= &order->item_ptr;
 
179
  }
 
180
  for (ORDER *order= (ORDER *)global_parameters->order_list.first;
 
181
       order;
 
182
       order=order->next)
 
183
  {
 
184
    (*order->item)->walk(&Item::change_context_processor, 0,
 
185
                         (uchar*) &fake_select_lex->context);
 
186
  }
 
187
}
 
188
 
 
189
 
 
190
bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
 
191
                                 ulong additional_options)
 
192
{
 
193
  SELECT_LEX *lex_select_save= thd_arg->lex->current_select;
 
194
  SELECT_LEX *sl, *first_sl= first_select();
 
195
  select_result *tmp_result;
 
196
  bool is_union_select;
 
197
  TABLE *empty_table= 0;
 
198
  DBUG_ENTER("st_select_lex_unit::prepare");
 
199
 
 
200
  describe= test(additional_options & SELECT_DESCRIBE);
 
201
 
 
202
  /*
 
203
    result object should be reassigned even if preparing already done for
 
204
    max/min subquery (ALL/ANY optimization)
 
205
  */
 
206
  result= sel_result;
 
207
 
 
208
  if (prepared)
 
209
  {
 
210
    if (describe)
 
211
    {
 
212
      /* fast reinit for EXPLAIN */
 
213
      for (sl= first_sl; sl; sl= sl->next_select())
 
214
      {
 
215
        sl->join->result= result;
 
216
        select_limit_cnt= HA_POS_ERROR;
 
217
        offset_limit_cnt= 0;
 
218
        if (result->prepare(sl->join->fields_list, this))
 
219
        {
 
220
          DBUG_RETURN(TRUE);
 
221
        }
 
222
        sl->join->select_options|= SELECT_DESCRIBE;
 
223
        sl->join->reinit();
 
224
      }
 
225
    }
 
226
    DBUG_RETURN(FALSE);
 
227
  }
 
228
  prepared= 1;
 
229
  saved_error= FALSE;
 
230
  
 
231
  thd_arg->lex->current_select= sl= first_sl;
 
232
  found_rows_for_union= first_sl->options & OPTION_FOUND_ROWS;
 
233
  is_union_select= is_union() || fake_select_lex;
 
234
 
 
235
  /* Global option */
 
236
 
 
237
  if (is_union_select)
 
238
  {
 
239
    if (!(tmp_result= union_result= new select_union))
 
240
      goto err;
 
241
    if (describe)
 
242
      tmp_result= sel_result;
 
243
  }
 
244
  else
 
245
    tmp_result= sel_result;
 
246
 
 
247
  sl->context.resolve_in_select_list= TRUE;
 
248
 
 
249
  for (;sl; sl= sl->next_select())
 
250
  {
 
251
    bool can_skip_order_by;
 
252
    sl->options|=  SELECT_NO_UNLOCK;
 
253
    JOIN *join= new JOIN(thd_arg, sl->item_list, 
 
254
                         sl->options | thd_arg->options | additional_options,
 
255
                         tmp_result);
 
256
    /*
 
257
      setup_tables_done_option should be set only for very first SELECT,
 
258
      because it protect from secont setup_tables call for select-like non
 
259
      select commands (DELETE/INSERT/...) and they use only very first
 
260
      SELECT (for union it can be only INSERT ... SELECT).
 
261
    */
 
262
    additional_options&= ~OPTION_SETUP_TABLES_DONE;
 
263
    if (!join)
 
264
      goto err;
 
265
 
 
266
    thd_arg->lex->current_select= sl;
 
267
 
 
268
    can_skip_order_by= is_union_select && !(sl->braces && sl->explicit_limit);
 
269
 
 
270
    saved_error= join->prepare(&sl->ref_pointer_array,
 
271
                               (TABLE_LIST*) sl->table_list.first,
 
272
                               sl->with_wild,
 
273
                               sl->where,
 
274
                               (can_skip_order_by ? 0 :
 
275
                                sl->order_list.elements) +
 
276
                               sl->group_list.elements,
 
277
                               can_skip_order_by ?
 
278
                               (ORDER*) 0 : (ORDER *)sl->order_list.first,
 
279
                               (ORDER*) sl->group_list.first,
 
280
                               sl->having,
 
281
                               (is_union_select ? (ORDER*) 0 :
 
282
                                (ORDER*) thd_arg->lex->proc_list.first),
 
283
                               sl, this);
 
284
    /* There are no * in the statement anymore (for PS) */
 
285
    sl->with_wild= 0;
 
286
 
 
287
    if (saved_error || (saved_error= thd_arg->is_fatal_error))
 
288
      goto err;
 
289
    /*
 
290
      Use items list of underlaid select for derived tables to preserve
 
291
      information about fields lengths and exact types
 
292
    */
 
293
    if (!is_union_select)
 
294
      types= first_sl->item_list;
 
295
    else if (sl == first_sl)
 
296
    {
 
297
      /*
 
298
        We need to create an empty table object. It is used
 
299
        to create tmp_table fields in Item_type_holder.
 
300
        The main reason of this is that we can't create
 
301
        field object without table.
 
302
      */
 
303
      DBUG_ASSERT(!empty_table);
 
304
      empty_table= (TABLE*) thd->calloc(sizeof(TABLE));
 
305
      types.empty();
 
306
      List_iterator_fast<Item> it(sl->item_list);
 
307
      Item *item_tmp;
 
308
      while ((item_tmp= it++))
 
309
      {
 
310
        /* Error's in 'new' will be detected after loop */
 
311
        types.push_back(new Item_type_holder(thd_arg, item_tmp));
 
312
      }
 
313
 
 
314
      if (thd_arg->is_fatal_error)
 
315
        goto err; // out of memory
 
316
    }
 
317
    else
 
318
    {
 
319
      if (types.elements != sl->item_list.elements)
 
320
      {
 
321
        my_message(ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT,
 
322
                   ER(ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT),MYF(0));
 
323
        goto err;
 
324
      }
 
325
      List_iterator_fast<Item> it(sl->item_list);
 
326
      List_iterator_fast<Item> tp(types);       
 
327
      Item *type, *item_tmp;
 
328
      while ((type= tp++, item_tmp= it++))
 
329
      {
 
330
        if (((Item_type_holder*)type)->join_types(thd_arg, item_tmp))
 
331
          DBUG_RETURN(TRUE);
 
332
      }
 
333
    }
 
334
  }
 
335
 
 
336
  if (is_union_select)
 
337
  {
 
338
    /*
 
339
      Check that it was possible to aggregate
 
340
      all collations together for UNION.
 
341
    */
 
342
    List_iterator_fast<Item> tp(types);
 
343
    Item *type;
 
344
    ulonglong create_options;
 
345
 
 
346
    while ((type= tp++))
 
347
    {
 
348
      if (type->result_type() == STRING_RESULT &&
 
349
          type->collation.derivation == DERIVATION_NONE)
 
350
      {
 
351
        my_error(ER_CANT_AGGREGATE_NCOLLATIONS, MYF(0), "UNION");
 
352
        goto err;
 
353
      }
 
354
    }
 
355
    
 
356
    create_options= (first_sl->options | thd_arg->options |
 
357
                     TMP_TABLE_ALL_COLUMNS);
 
358
 
 
359
    if (union_result->create_result_table(thd, &types, test(union_distinct),
 
360
                                          create_options, "", FALSE))
 
361
      goto err;
 
362
    bzero((char*) &result_table_list, sizeof(result_table_list));
 
363
    result_table_list.db= (char*) "";
 
364
    result_table_list.table_name= result_table_list.alias= (char*) "union";
 
365
    result_table_list.table= table= union_result->table;
 
366
 
 
367
    thd_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
    }
 
374
    else
 
375
    {
 
376
      DBUG_ASSERT(thd->stmt_arena->is_conventional() == false);
 
377
      /*
 
378
        We're in execution of a prepared statement or stored procedure:
 
379
        reset field items to point at fields from the created temporary table.
 
380
      */
 
381
      table->reset_item_list(&item_list);
 
382
    }
 
383
  }
 
384
 
 
385
  thd_arg->lex->current_select= lex_select_save;
 
386
 
 
387
  DBUG_RETURN(saved_error || thd_arg->is_fatal_error);
 
388
 
 
389
err:
 
390
  thd_arg->lex->current_select= lex_select_save;
 
391
  DBUG_RETURN(TRUE);
 
392
}
 
393
 
 
394
 
 
395
bool st_select_lex_unit::exec()
 
396
{
 
397
  SELECT_LEX *lex_select_save= thd->lex->current_select;
 
398
  SELECT_LEX *select_cursor=first_select();
 
399
  ulonglong add_rows=0;
 
400
  ha_rows examined_rows= 0;
 
401
  DBUG_ENTER("st_select_lex_unit::exec");
 
402
 
 
403
  if (executed && !uncacheable && !describe)
 
404
    DBUG_RETURN(FALSE);
 
405
  executed= 1;
 
406
  
 
407
  if (uncacheable || !item || !item->assigned() || describe)
 
408
  {
 
409
    if (item)
 
410
      item->reset_value_registration();
 
411
    if (optimized && item)
 
412
    {
 
413
      if (item->assigned())
 
414
      {
 
415
        item->assigned(0); // We will reinit & rexecute unit
 
416
        item->reset();
 
417
        table->file->ha_delete_all_rows();
 
418
      }
 
419
      /* re-enabling indexes for next subselect iteration */
 
420
      if (union_distinct && table->file->ha_enable_indexes(HA_KEY_SWITCH_ALL))
 
421
      {
 
422
        DBUG_ASSERT(0);
 
423
      }
 
424
    }
 
425
    for (SELECT_LEX *sl= select_cursor; sl; sl= sl->next_select())
 
426
    {
 
427
      ha_rows records_at_start= 0;
 
428
      thd->lex->current_select= sl;
 
429
 
 
430
      if (optimized)
 
431
        saved_error= sl->join->reinit();
 
432
      else
 
433
      {
 
434
        set_limit(sl);
 
435
        if (sl == global_parameters || describe)
 
436
        {
 
437
          offset_limit_cnt= 0;
 
438
          /*
 
439
            We can't use LIMIT at this stage if we are using ORDER BY for the
 
440
            whole query
 
441
          */
 
442
          if (sl->order_list.first || describe)
 
443
            select_limit_cnt= HA_POS_ERROR;
 
444
        }
 
445
 
 
446
        /*
 
447
          When using braces, SQL_CALC_FOUND_ROWS affects the whole query:
 
448
          we don't calculate found_rows() per union part.
 
449
          Otherwise, SQL_CALC_FOUND_ROWS should be done on all sub parts.
 
450
        */
 
451
        sl->join->select_options= 
 
452
          (select_limit_cnt == HA_POS_ERROR || sl->braces) ?
 
453
          sl->options & ~OPTION_FOUND_ROWS : sl->options | found_rows_for_union;
 
454
 
 
455
        /* dump_TABLE_LIST_struct(select_lex, select_lex->leaf_tables); */
 
456
        if (sl->join->flatten_subqueries())
 
457
          DBUG_RETURN(TRUE);
 
458
 
 
459
        /* dump_TABLE_LIST_struct(select_lex, select_lex->leaf_tables); */
 
460
        saved_error= sl->join->optimize();
 
461
      }
 
462
      if (!saved_error)
 
463
      {
 
464
        records_at_start= table->file->stats.records;
 
465
        sl->join->exec();
 
466
        if (sl == union_distinct)
 
467
        {
 
468
          if (table->file->ha_disable_indexes(HA_KEY_SWITCH_ALL))
 
469
            DBUG_RETURN(TRUE);
 
470
          table->no_keyread=1;
 
471
        }
 
472
        saved_error= sl->join->error;
 
473
        offset_limit_cnt= (ha_rows)(sl->offset_limit ?
 
474
                                    sl->offset_limit->val_uint() :
 
475
                                    0);
 
476
        if (!saved_error)
 
477
        {
 
478
          examined_rows+= thd->examined_row_count;
 
479
          if (union_result->flush())
 
480
          {
 
481
            thd->lex->current_select= lex_select_save;
 
482
            DBUG_RETURN(1);
 
483
          }
 
484
        }
 
485
      }
 
486
      if (saved_error)
 
487
      {
 
488
        thd->lex->current_select= lex_select_save;
 
489
        DBUG_RETURN(saved_error);
 
490
      }
 
491
      /* Needed for the following test and for records_at_start in next loop */
 
492
      int error= table->file->info(HA_STATUS_VARIABLE);
 
493
      if(error)
 
494
      {
 
495
        table->file->print_error(error, MYF(0));
 
496
        DBUG_RETURN(1);
 
497
      }
 
498
      if (found_rows_for_union && !sl->braces && 
 
499
          select_limit_cnt != HA_POS_ERROR)
 
500
      {
 
501
        /*
 
502
          This is a union without braces. Remember the number of rows that
 
503
          could also have been part of the result set.
 
504
          We get this from the difference of between total number of possible
 
505
          rows and actual rows added to the temporary table.
 
506
        */
 
507
        add_rows+= (ulonglong) (thd->limit_found_rows - (ulonglong)
 
508
                              ((table->file->stats.records -  records_at_start)));
 
509
      }
 
510
    }
 
511
  }
 
512
  optimized= 1;
 
513
 
 
514
  /* Send result to 'result' */
 
515
  saved_error= TRUE;
 
516
  {
 
517
    if (!thd->is_fatal_error)                           // Check if EOM
 
518
    {
 
519
      set_limit(global_parameters);
 
520
      init_prepare_fake_select_lex(thd);
 
521
      JOIN *join= fake_select_lex->join;
 
522
      if (!join)
 
523
      {
 
524
        /*
 
525
          allocate JOIN for fake select only once (prevent
 
526
          mysql_select automatic allocation)
 
527
          TODO: The above is nonsense. mysql_select() will not allocate the
 
528
          join if one already exists. There must be some other reason why we
 
529
          don't let it allocate the join. Perhaps this is because we need
 
530
          some special parameter values passed to join constructor?
 
531
        */
 
532
        if (!(fake_select_lex->join= new JOIN(thd, item_list,
 
533
                                              fake_select_lex->options, result)))
 
534
        {
 
535
          fake_select_lex->table_list.empty();
 
536
          DBUG_RETURN(TRUE);
 
537
        }
 
538
        fake_select_lex->join->no_const_tables= TRUE;
 
539
 
 
540
        /*
 
541
          Fake st_select_lex should have item list for correctref_array
 
542
          allocation.
 
543
        */
 
544
        fake_select_lex->item_list= item_list;
 
545
        saved_error= mysql_select(thd, &fake_select_lex->ref_pointer_array,
 
546
                              &result_table_list,
 
547
                              0, item_list, NULL,
 
548
                              global_parameters->order_list.elements,
 
549
                              (ORDER*)global_parameters->order_list.first,
 
550
                              (ORDER*) NULL, NULL, (ORDER*) NULL,
 
551
                              fake_select_lex->options | SELECT_NO_UNLOCK,
 
552
                              result, this, fake_select_lex);
 
553
      }
 
554
      else
 
555
      {
 
556
        if (describe)
 
557
        {
 
558
          /*
 
559
            In EXPLAIN command, constant subqueries that do not use any
 
560
            tables are executed two times:
 
561
             - 1st time is a real evaluation to get the subquery value
 
562
             - 2nd time is to produce EXPLAIN output rows.
 
563
            1st execution sets certain members (e.g. select_result) to perform
 
564
            subquery execution rather than EXPLAIN line production. In order 
 
565
            to reset them back, we re-do all of the actions (yes it is ugly):
 
566
          */
 
567
          join->init(thd, item_list, fake_select_lex->options, result);
 
568
          saved_error= mysql_select(thd, &fake_select_lex->ref_pointer_array,
 
569
                                &result_table_list,
 
570
                                0, item_list, NULL,
 
571
                                global_parameters->order_list.elements,
 
572
                                (ORDER*)global_parameters->order_list.first,
 
573
                                (ORDER*) NULL, NULL, (ORDER*) NULL,
 
574
                                fake_select_lex->options | SELECT_NO_UNLOCK,
 
575
                                result, this, fake_select_lex);
 
576
        }
 
577
        else
 
578
        {
 
579
          join->examined_rows= 0;
 
580
          saved_error= join->reinit();
 
581
          join->exec();
 
582
        }
 
583
      }
 
584
 
 
585
      fake_select_lex->table_list.empty();
 
586
      if (!saved_error)
 
587
      {
 
588
        thd->limit_found_rows = (ulonglong)table->file->stats.records + add_rows;
 
589
        thd->examined_row_count+= examined_rows;
 
590
      }
 
591
      /*
 
592
        Mark for slow query log if any of the union parts didn't use
 
593
        indexes efficiently
 
594
      */
 
595
    }
 
596
  }
 
597
  thd->lex->current_select= lex_select_save;
 
598
  DBUG_RETURN(saved_error);
 
599
}
 
600
 
 
601
 
 
602
bool st_select_lex_unit::cleanup()
 
603
{
 
604
  int error= 0;
 
605
  DBUG_ENTER("st_select_lex_unit::cleanup");
 
606
 
 
607
  if (cleaned)
 
608
  {
 
609
    DBUG_RETURN(FALSE);
 
610
  }
 
611
  cleaned= 1;
 
612
 
 
613
  if (union_result)
 
614
  {
 
615
    delete union_result;
 
616
    union_result=0; // Safety
 
617
    if (table)
 
618
      free_tmp_table(thd, table);
 
619
    table= 0; // Safety
 
620
  }
 
621
 
 
622
  for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select())
 
623
    error|= sl->cleanup();
 
624
 
 
625
  if (fake_select_lex)
 
626
  {
 
627
    JOIN *join;
 
628
    if ((join= fake_select_lex->join))
 
629
    {
 
630
      join->tables_list= 0;
 
631
      join->tables= 0;
 
632
    }
 
633
    error|= fake_select_lex->cleanup();
 
634
    if (fake_select_lex->order_list.elements)
 
635
    {
 
636
      ORDER *ord;
 
637
      for (ord= (ORDER*)fake_select_lex->order_list.first; ord; ord= ord->next)
 
638
        (*ord->item)->cleanup();
 
639
    }
 
640
  }
 
641
 
 
642
  DBUG_RETURN(error);
 
643
}
 
644
 
 
645
 
 
646
void st_select_lex_unit::reinit_exec_mechanism()
 
647
{
 
648
  prepared= optimized= executed= 0;
 
649
#ifndef DBUG_OFF
 
650
  if (is_union())
 
651
  {
 
652
    List_iterator_fast<Item> it(item_list);
 
653
    Item *field;
 
654
    while ((field= it++))
 
655
    {
 
656
      /*
 
657
        we can't cleanup here, because it broke link to temporary table field,
 
658
        but have to drop fixed flag to allow next fix_field of this field
 
659
        during re-executing
 
660
      */
 
661
      field->fixed= 0;
 
662
    }
 
663
  }
 
664
#endif
 
665
}
 
666
 
 
667
 
 
668
/*
 
669
  change select_result object of unit
 
670
 
 
671
  SYNOPSIS
 
672
    st_select_lex_unit::change_result()
 
673
    result      new select_result object
 
674
    old_result  old select_result object
 
675
 
 
676
  RETURN
 
677
    FALSE - OK
 
678
    TRUE  - error
 
679
*/
 
680
 
 
681
bool st_select_lex_unit::change_result(select_result_interceptor *new_result,
 
682
                                       select_result_interceptor *old_result)
 
683
{
 
684
  bool res= FALSE;
 
685
  for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select())
 
686
  {
 
687
    if (sl->join && sl->join->result == old_result)
 
688
      if (sl->join->change_result(new_result))
 
689
        return TRUE;
 
690
  }
 
691
  if (fake_select_lex && fake_select_lex->join)
 
692
    res= fake_select_lex->join->change_result(new_result);
 
693
  return (res);
 
694
}
 
695
 
 
696
/*
 
697
  Get column type information for this unit.
 
698
 
 
699
  SYNOPSIS
 
700
    st_select_lex_unit::get_unit_column_types()
 
701
 
 
702
  DESCRIPTION
 
703
    For a single-select the column types are taken
 
704
    from the list of selected items. For a union this function
 
705
    assumes that st_select_lex_unit::prepare has been called
 
706
    and returns the type holders that were created for unioned
 
707
    column types of all selects.
 
708
 
 
709
  NOTES
 
710
    The implementation of this function should be in sync with
 
711
    st_select_lex_unit::prepare()
 
712
*/
 
713
 
 
714
List<Item> *st_select_lex_unit::get_unit_column_types()
 
715
{
 
716
  SELECT_LEX *sl= first_select();
 
717
 
 
718
  if (is_union())
 
719
  {
 
720
    DBUG_ASSERT(prepared);
 
721
    /* Types are generated during prepare */
 
722
    return &types;
 
723
  }
 
724
 
 
725
  return &sl->item_list;
 
726
}
 
727
 
 
728
bool st_select_lex::cleanup()
 
729
{
 
730
  bool error= FALSE;
 
731
  DBUG_ENTER("st_select_lex::cleanup()");
 
732
 
 
733
  if (join)
 
734
  {
 
735
    DBUG_ASSERT((st_select_lex*)join->select_lex == this);
 
736
    error= join->destroy();
 
737
    delete join;
 
738
    join= 0;
 
739
  }
 
740
  for (SELECT_LEX_UNIT *lex_unit= first_inner_unit(); lex_unit ;
 
741
       lex_unit= lex_unit->next_unit())
 
742
  {
 
743
    error= (bool) ((uint) error | (uint) lex_unit->cleanup());
 
744
  }
 
745
  non_agg_fields.empty();
 
746
  inner_refs_list.empty();
 
747
  DBUG_RETURN(error);
 
748
}
 
749
 
 
750
 
 
751
void st_select_lex::cleanup_all_joins(bool full)
 
752
{
 
753
  SELECT_LEX_UNIT *unit;
 
754
  SELECT_LEX *sl;
 
755
 
 
756
  if (join)
 
757
    join->cleanup(full);
 
758
 
 
759
  for (unit= first_inner_unit(); unit; unit= unit->next_unit())
 
760
    for (sl= unit->first_select(); sl; sl= sl->next_select())
 
761
      sl->cleanup_all_joins(full);
 
762
}