~drizzle-trunk/drizzle/development

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