sql_select.cc 417 KB
Newer Older
unknown's avatar
af  
unknown committed
1
/* Copyright (C) 2000-2004 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
unknown's avatar
unknown committed
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */


/* mysql_select and join optimization */

20
#ifdef USE_PRAGMA_IMPLEMENTATION
unknown's avatar
unknown committed
21 22 23 24 25
#pragma implementation				// gcc: Class implementation
#endif

#include "mysql_priv.h"
#include "sql_select.h"
unknown's avatar
unknown committed
26

unknown's avatar
unknown committed
27 28 29 30 31
#include <m_ctype.h>
#include <hash.h>
#include <ft_global.h>

const char *join_type_str[]={ "UNKNOWN","system","const","eq_ref","ref",
32
			      "MAYBE_REF","ALL","range","index","fulltext",
33
			      "ref_or_null","unique_subquery","index_subquery",
unknown's avatar
unknown committed
34
                              "index_merge"
35
};
unknown's avatar
unknown committed
36

37
static void optimize_keyuse(JOIN *join, DYNAMIC_ARRAY *keyuse_array);
38
static bool make_join_statistics(JOIN *join, TABLE_LIST *leaves, COND *conds,
unknown's avatar
unknown committed
39
				 DYNAMIC_ARRAY *keyuse);
40 41
static bool update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,
				JOIN_TAB *join_tab,
42
                                uint tables, COND *conds,
unknown's avatar
unknown committed
43
                                COND_EQUAL *cond_equal,
44
				table_map table_map, SELECT_LEX *select_lex);
unknown's avatar
unknown committed
45 46
static int sort_keyuse(KEYUSE *a,KEYUSE *b);
static void set_position(JOIN *join,uint index,JOIN_TAB *table,KEYUSE *key);
47 48
static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, KEYUSE *org_keyuse,
			       table_map used_tables);
unknown's avatar
af  
unknown committed
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
static void choose_plan(JOIN *join,table_map join_tables);

static void best_access_path(JOIN *join, JOIN_TAB *s, THD *thd,
                             table_map remaining_tables, uint idx,
                             double record_count, double read_time);
static void optimize_straight_join(JOIN *join, table_map join_tables);
static void greedy_search(JOIN *join, table_map remaining_tables,
                             uint depth, uint prune_level);
static void best_extension_by_limited_search(JOIN *join,
                                             table_map remaining_tables,
                                             uint idx, double record_count,
                                             double read_time, uint depth,
                                             uint prune_level);
static uint determine_search_depth(JOIN* join);
static int join_tab_cmp(const void* ptr1, const void* ptr2);
64
static int join_tab_cmp_straight(const void* ptr1, const void* ptr2);
unknown's avatar
af  
unknown committed
65 66 67 68
/*
  TODO: 'find_best' is here only temporarily until 'greedy_search' is
  tested and approved.
*/
unknown's avatar
unknown committed
69 70 71 72 73
static void find_best(JOIN *join,table_map rest_tables,uint index,
		      double record_count,double read_time);
static uint cache_record_length(JOIN *join,uint index);
static double prev_record_reads(JOIN *join,table_map found_ref);
static bool get_best_combination(JOIN *join);
unknown's avatar
unknown committed
74 75
static store_key *get_store_key(THD *thd,
				KEYUSE *keyuse, table_map used_tables,
unknown's avatar
unknown committed
76 77 78
				KEY_PART_INFO *key_part, char *key_buff,
				uint maybe_null);
static bool make_simple_join(JOIN *join,TABLE *tmp_table);
79
static void make_outerjoin_info(JOIN *join);
unknown's avatar
unknown committed
80 81
static bool make_join_select(JOIN *join,SQL_SELECT *select,COND *item);
static void make_join_readinfo(JOIN *join,uint options);
82
static bool only_eq_ref_tables(JOIN *join, ORDER *order, table_map tables);
unknown's avatar
unknown committed
83 84 85
static void update_depend_map(JOIN *join);
static void update_depend_map(JOIN *join, ORDER *order);
static ORDER *remove_const(JOIN *join,ORDER *first_order,COND *cond,
86
			   bool change_list, bool *simple_order);
87
static int return_zero_rows(JOIN *join, select_result *res,TABLE_LIST *tables,
unknown's avatar
unknown committed
88 89
			    List<Item> &fields, bool send_row,
			    uint select_options, const char *info,
90 91
			    Item *having, Procedure *proc,
			    SELECT_LEX_UNIT *unit);
unknown's avatar
unknown committed
92
static COND *build_equal_items(THD *thd, COND *cond,
unknown's avatar
unknown committed
93 94 95
                               COND_EQUAL *inherited,
                               List<TABLE_LIST> *join_list,
                               COND_EQUAL **cond_equal_ref);
96
static COND* substitute_for_best_equal_field(COND *cond,
unknown's avatar
unknown committed
97
                                             COND_EQUAL *cond_equal,
98
                                             void *table_join_idx);
99 100
static COND *simplify_joins(JOIN *join, List<TABLE_LIST> *join_list,
                            COND *conds, bool top);
unknown's avatar
unknown committed
101
static COND *optimize_cond(JOIN *join, COND *conds,
unknown's avatar
unknown committed
102
                           List<TABLE_LIST> *join_list,
unknown's avatar
af  
unknown committed
103
			   Item::cond_result *cond_value);
104
static bool resolve_nested_join (TABLE_LIST *table);
unknown's avatar
af  
unknown committed
105 106
static COND *remove_eq_conds(THD *thd, COND *cond, 
			     Item::cond_result *cond_value);
unknown's avatar
unknown committed
107 108 109
static bool const_expression_in_where(COND *conds,Item *item, Item **comp_item);
static bool open_tmp_table(TABLE *table);
static bool create_myisam_tmp_table(TABLE *table,TMP_TABLE_PARAM *param,
110
				    ulong options);
111
static Next_select_func setup_end_select_func(JOIN *join);
unknown's avatar
unknown committed
112 113
static int do_select(JOIN *join,List<Item> *fields,TABLE *tmp_table,
		     Procedure *proc);
114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138

static enum_nested_loop_state
sub_select_cache(JOIN *join, JOIN_TAB *join_tab, bool end_of_records);
static enum_nested_loop_state
evaluate_join_record(JOIN *join, JOIN_TAB *join_tab,
                     int error, my_bool *report_error);
static enum_nested_loop_state
evaluate_null_complemented_join_record(JOIN *join, JOIN_TAB *join_tab);
static enum_nested_loop_state
sub_select(JOIN *join,JOIN_TAB *join_tab, bool end_of_records);
static enum_nested_loop_state
flush_cached_records(JOIN *join, JOIN_TAB *join_tab, bool skip_last);
static enum_nested_loop_state
end_send(JOIN *join, JOIN_TAB *join_tab, bool end_of_records);
static enum_nested_loop_state
end_send_group(JOIN *join, JOIN_TAB *join_tab, bool end_of_records);
static enum_nested_loop_state
end_write(JOIN *join, JOIN_TAB *join_tab, bool end_of_records);
static enum_nested_loop_state
end_update(JOIN *join, JOIN_TAB *join_tab, bool end_of_records);
static enum_nested_loop_state
end_unique_update(JOIN *join, JOIN_TAB *join_tab, bool end_of_records);
static enum_nested_loop_state
end_write_group(JOIN *join, JOIN_TAB *join_tab, bool end_of_records);

unknown's avatar
unknown committed
139
static int test_if_group_changed(List<Cached_item> &list);
140
static int join_read_const_table(JOIN_TAB *tab, POSITION *pos);
unknown's avatar
unknown committed
141 142 143 144
static int join_read_system(JOIN_TAB *tab);
static int join_read_const(JOIN_TAB *tab);
static int join_read_key(JOIN_TAB *tab);
static int join_read_always_key(JOIN_TAB *tab);
145
static int join_read_last_key(JOIN_TAB *tab);
unknown's avatar
unknown committed
146 147 148 149 150
static int join_no_more_records(READ_RECORD *info);
static int join_read_next(READ_RECORD *info);
static int join_init_quick_read_record(JOIN_TAB *tab);
static int test_if_quick_select(JOIN_TAB *tab);
static int join_init_read_record(JOIN_TAB *tab);
151 152 153 154 155 156
static int join_read_first(JOIN_TAB *tab);
static int join_read_next(READ_RECORD *info);
static int join_read_next_same(READ_RECORD *info);
static int join_read_last(JOIN_TAB *tab);
static int join_read_prev_same(READ_RECORD *info);
static int join_read_prev(READ_RECORD *info);
unknown's avatar
unknown committed
157 158
static int join_ft_read_first(JOIN_TAB *tab);
static int join_ft_read_next(READ_RECORD *info);
159 160
static int join_read_always_key_or_null(JOIN_TAB *tab);
static int join_read_next_same_or_null(READ_RECORD *info);
unknown's avatar
unknown committed
161 162 163
static COND *make_cond_for_table(COND *cond,table_map table,
				 table_map used_table);
static Item* part_of_refkey(TABLE *form,Field *field);
164
uint find_shortest_key(TABLE *table, const key_map *usable_keys);
unknown's avatar
unknown committed
165
static bool test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,
166
				    ha_rows select_limit, bool no_changes);
167
static int create_sort_index(THD *thd, JOIN *join, ORDER *order,
unknown's avatar
unknown committed
168
			     ha_rows filesort_limit, ha_rows select_limit);
169 170
static int remove_duplicates(JOIN *join,TABLE *entry,List<Item> &fields,
			     Item *having);
unknown's avatar
unknown committed
171
static int remove_dup_with_compare(THD *thd, TABLE *entry, Field **field,
172
				   ulong offset,Item *having);
unknown's avatar
unknown committed
173
static int remove_dup_with_hash_index(THD *thd,TABLE *table,
unknown's avatar
unknown committed
174
				      uint field_count, Field **first_field,
175

176
				      ulong key_length,Item *having);
unknown's avatar
unknown committed
177 178 179
static int join_init_cache(THD *thd,JOIN_TAB *tables,uint table_count);
static ulong used_blob_length(CACHE_FIELD **ptr);
static bool store_record_in_cache(JOIN_CACHE *cache);
180 181
static void reset_cache_read(JOIN_CACHE *cache);
static void reset_cache_write(JOIN_CACHE *cache);
unknown's avatar
unknown committed
182 183 184 185
static void read_cached_record(JOIN_TAB *tab);
static bool cmp_buffer_with_ref(JOIN_TAB *tab);
static bool setup_new_fields(THD *thd,TABLE_LIST *tables,List<Item> &fields,
			     List<Item> &all_fields,ORDER *new_order);
186 187 188
static ORDER *create_distinct_group(THD *thd, ORDER *order,
				    List<Item> &fields,
				    bool *all_order_by_fields_used);
unknown's avatar
unknown committed
189 190 191
static bool test_if_subpart(ORDER *a,ORDER *b);
static TABLE *get_sort_by_table(ORDER *a,ORDER *b,TABLE_LIST *tables);
static void calc_group_buffer(JOIN *join,ORDER *group);
192
static bool make_group_fields(JOIN *main_join, JOIN *curr_join);
unknown's avatar
unknown committed
193
static bool alloc_group_fields(JOIN *join,ORDER *group);
194
// Create list for using with tempory table
195
static bool change_to_use_tmp_fields(THD *thd, Item **ref_pointer_array,
196 197 198 199 200 201 202 203
				     List<Item> &new_list1,
				     List<Item> &new_list2,
				     uint elements, List<Item> &items);
// Create list for using with tempory table
static bool change_refs_to_tmp_fields(THD *thd, Item **ref_pointer_array,
				      List<Item> &new_list1,
				      List<Item> &new_list2,
				      uint elements, List<Item> &items);
unknown's avatar
unknown committed
204 205
static void init_tmptable_sum_functions(Item_sum **func);
static void update_tmptable_sum_func(Item_sum **func,TABLE *tmp_table);
unknown's avatar
unknown committed
206
static void copy_sum_funcs(Item_sum **func_ptr, Item_sum **end);
unknown's avatar
unknown committed
207
static bool add_ref_to_table_cond(THD *thd, JOIN_TAB *join_tab);
208
static bool setup_sum_funcs(THD *thd, Item_sum **func_ptr);
209
static bool init_sum_functions(Item_sum **func, Item_sum **end);
unknown's avatar
unknown committed
210
static bool update_sum_func(Item_sum **func);
211
static void select_describe(JOIN *join, bool need_tmp_table,bool need_order,
unknown's avatar
unknown committed
212
			    bool distinct, const char *message=NullS);
213
static Item *remove_additional_cond(Item* conds);
214
static void add_group_and_distinct_keys(JOIN *join, JOIN_TAB *join_tab);
unknown's avatar
unknown committed
215

216

217 218 219 220
/*
  This handles SELECT with and without UNION
*/

221 222
bool handle_select(THD *thd, LEX *lex, select_result *result,
                   ulong setup_tables_done_option)
223
{
unknown's avatar
unknown committed
224
  bool res;
225
  register SELECT_LEX *select_lex = &lex->select_lex;
226 227
  DBUG_ENTER("handle_select");

unknown's avatar
unknown committed
228
  if (select_lex->next_select())
229
    res= mysql_union(thd, lex, result, &lex->unit, setup_tables_done_option);
230
  else
unknown's avatar
af  
unknown committed
231 232
  {
    SELECT_LEX_UNIT *unit= &lex->unit;
233
    unit->set_limit(unit->global_parameters);
234 235 236 237 238
    /*
      'options' of mysql_select will be set in JOIN, as far as JOIN for
      every PS/SP execution new, we will not need reset this flag if 
      setup_tables_done_option changed for next rexecution
    */
239 240 241 242 243 244 245 246 247 248
    res= mysql_select(thd, &select_lex->ref_pointer_array,
		      (TABLE_LIST*) select_lex->table_list.first,
		      select_lex->with_wild, select_lex->item_list,
		      select_lex->where,
		      select_lex->order_list.elements +
		      select_lex->group_list.elements,
		      (ORDER*) select_lex->order_list.first,
		      (ORDER*) select_lex->group_list.first,
		      select_lex->having,
		      (ORDER*) lex->proc_list.first,
249 250
		      select_lex->options | thd->options |
                      setup_tables_done_option,
unknown's avatar
af  
unknown committed
251 252
		      result, unit, select_lex);
  }
253 254
  DBUG_PRINT("info",("res: %d  report_error: %d", res,
		     thd->net.report_error));
unknown's avatar
unknown committed
255
  res|= thd->net.report_error;
256
  if (unlikely(res))
257
  {
258
    /* If we had a another error reported earlier then this will be ignored */
unknown's avatar
unknown committed
259
    result->send_error(ER_UNKNOWN_ERROR, ER(ER_UNKNOWN_ERROR));
260
    result->abort();
unknown's avatar
unknown committed
261
  }
262
  DBUG_RETURN(res);
263 264
}

265

266
/*
267
  Function to setup clauses without sum functions
268
*/
269 270
inline int setup_without_group(THD *thd, Item **ref_pointer_array,
			       TABLE_LIST *tables,
271
			       TABLE_LIST *leaves,
272 273 274 275 276 277
			       List<Item> &fields,
			       List<Item> &all_fields,
			       COND **conds,
			       ORDER *order,
			       ORDER *group, bool *hidden_group_fields)
{
unknown's avatar
af  
unknown committed
278 279 280 281 282
  bool save_allow_sum_func;
  int res;
  DBUG_ENTER("setup_without_group");

  save_allow_sum_func= thd->allow_sum_func;
283
  thd->allow_sum_func= 0;
unknown's avatar
unknown committed
284
  res= setup_conds(thd, tables, leaves, conds);
unknown's avatar
unknown committed
285 286 287 288 289 290
  thd->allow_sum_func= save_allow_sum_func;
  res= res || setup_order(thd, ref_pointer_array, tables, fields, all_fields,
                          order);
  thd->allow_sum_func= 0;
  res= res || setup_group(thd, ref_pointer_array, tables, fields, all_fields,
                          group, hidden_group_fields);
291
  thd->allow_sum_func= save_allow_sum_func;
unknown's avatar
af  
unknown committed
292
  DBUG_RETURN(res);
293 294
}

unknown's avatar
unknown committed
295
/*****************************************************************************
296 297
  Check fields, find best join, do the select and output fields.
  mysql_select assumes that all tables are already opened
unknown's avatar
unknown committed
298 299
*****************************************************************************/

300
/*
unknown's avatar
af  
unknown committed
301
  Prepare of whole select (including sub queries in future).
302 303 304
  return -1 on error
          0 on success
*/
unknown's avatar
unknown committed
305
int
306 307 308 309
JOIN::prepare(Item ***rref_pointer_array,
	      TABLE_LIST *tables_init,
	      uint wild_num, COND *conds_init, uint og_num,
	      ORDER *order_init, ORDER *group_init,
unknown's avatar
unknown committed
310
	      Item *having_init,
311 312
	      ORDER *proc_param_init, SELECT_LEX *select_lex_arg,
	      SELECT_LEX_UNIT *unit_arg)
unknown's avatar
unknown committed
313
{
314
  DBUG_ENTER("JOIN::prepare");
unknown's avatar
unknown committed
315

unknown's avatar
af  
unknown committed
316 317 318 319
  // to prevent double initialization on EXPLAIN
  if (optimized)
    DBUG_RETURN(0);

320 321 322 323 324 325
  conds= conds_init;
  order= order_init;
  group_list= group_init;
  having= having_init;
  proc_param= proc_param_init;
  tables_list= tables_init;
326
  select_lex= select_lex_arg;
327
  select_lex->join= this;
328
  join_list= &select_lex->top_join_list;
329
  union_part= (unit_arg->first_select()->next_select() != 0);
unknown's avatar
unknown committed
330

331 332 333 334 335 336 337
  /*
    If we have already executed SELECT, then it have not sense to prevent
    its table from update (see unique_table())
  */
  if (thd->derived_tables_processing)
    select_lex->exclude_from_table_unique_test= TRUE;

unknown's avatar
unknown committed
338 339
  /* Check that all tables, fields, conds and order are ok */

340 341
  if ((!(select_options & OPTION_SETUP_TABLES_DONE) &&
       setup_tables(thd, tables_list, &conds, &select_lex->leaf_tables,
342
                    FALSE)) ||
343
      setup_wild(thd, tables_list, fields_list, &all_fields, wild_num) ||
unknown's avatar
unknown committed
344
      select_lex->setup_ref_array(thd, og_num) ||
345 346
      setup_fields(thd, (*rref_pointer_array), tables_list, fields_list, 1,
		   &all_fields, 1) ||
347 348 349
      setup_without_group(thd, (*rref_pointer_array), tables_list,
			  select_lex->leaf_tables, fields_list,
			  all_fields, &conds, order, group_list,
350
			  &hidden_group_fields))
unknown's avatar
unknown committed
351 352
    DBUG_RETURN(-1);				/* purecov: inspected */

353
  ref_pointer_array= *rref_pointer_array;
354
  
unknown's avatar
unknown committed
355 356 357 358
  if (having)
  {
    thd->where="having clause";
    thd->allow_sum_func=1;
unknown's avatar
unknown committed
359
    select_lex->having_fix_field= 1;
unknown's avatar
af  
unknown committed
360 361 362
    bool having_fix_rc= (!having->fixed &&
			 (having->fix_fields(thd, tables_list, &having) ||
			  having->check_cols(1)));
unknown's avatar
unknown committed
363
    select_lex->having_fix_field= 0;
unknown's avatar
unknown committed
364
    if (having_fix_rc || thd->net.report_error)
unknown's avatar
unknown committed
365 366
      DBUG_RETURN(-1);				/* purecov: inspected */
    if (having->with_sum_func)
367
      having->split_sum_func(thd, ref_pointer_array, all_fields);
unknown's avatar
unknown committed
368
  }
369

unknown's avatar
VIEW  
unknown committed
370
  if (!thd->lex->view_prepare_mode)
371 372
  {
    Item_subselect *subselect;
unknown's avatar
VIEW  
unknown committed
373
    /* Is it subselect? */
unknown's avatar
af  
unknown committed
374
    if ((subselect= select_lex->master_unit()->item))
375 376
    {
      Item_subselect::trans_res res;
377
      if ((res= subselect->select_transformer(this)) !=
378
	  Item_subselect::RES_OK)
unknown's avatar
af  
unknown committed
379
      {
unknown's avatar
VIEW  
unknown committed
380
        select_lex->fix_prepare_information(thd, &conds);
381
	DBUG_RETURN((res == Item_subselect::RES_ERROR));
unknown's avatar
af  
unknown committed
382
      }
383 384 385
    }
  }

386
  if (setup_ftfuncs(select_lex)) /* should be after having->fix_fields */
unknown's avatar
unknown committed
387
    DBUG_RETURN(-1);
388 389
  

unknown's avatar
unknown committed
390 391 392 393 394
  /*
    Check if one one uses a not constant column with group functions
    and no GROUP BY.
    TODO:  Add check of calculation of GROUP functions and fields:
	   SELECT COUNT(*)+table.col1 from table1;
395
  */
unknown's avatar
unknown committed
396
  {
397
    if (!group_list)
unknown's avatar
unknown committed
398 399
    {
      uint flag=0;
400
      List_iterator_fast<Item> it(fields_list);
unknown's avatar
unknown committed
401 402 403 404 405
      Item *item;
      while ((item= it++))
      {
	if (item->with_sum_func)
	  flag|=1;
unknown's avatar
af  
unknown committed
406
	else if (!(flag & 2) && !item->const_during_execution())
unknown's avatar
unknown committed
407 408 409 410
	  flag|=2;
      }
      if (flag == 3)
      {
unknown's avatar
unknown committed
411 412
	my_message(ER_MIX_OF_GROUP_FUNC_AND_FIELDS,
                   ER(ER_MIX_OF_GROUP_FUNC_AND_FIELDS), MYF(0));
unknown's avatar
unknown committed
413 414 415
	DBUG_RETURN(-1);
      }
    }
416
    TABLE_LIST *table_ptr;
417 418 419
    for (table_ptr= select_lex->leaf_tables;
	 table_ptr;
	 table_ptr= table_ptr->next_leaf)
420
      tables++;
unknown's avatar
unknown committed
421
  }
422 423 424
  {
    /* Caclulate the number of groups */
    send_group_parts= 0;
425
    for (ORDER *group_tmp= group_list ; group_tmp ; group_tmp= group_tmp->next)
426 427 428
      send_group_parts++;
  }
  
429
  procedure= setup_procedure(thd, proc_param, result, fields_list, &error);
unknown's avatar
unknown committed
430
  if (error)
431
    goto err;					/* purecov: inspected */
unknown's avatar
unknown committed
432 433
  if (procedure)
  {
434 435
    if (setup_new_fields(thd, tables_list, fields_list, all_fields,
			 procedure->param_fields))
436
	goto err;				/* purecov: inspected */
unknown's avatar
unknown committed
437 438
    if (procedure->group)
    {
439
      if (!test_if_subpart(procedure->group,group_list))
unknown's avatar
unknown committed
440
      {						/* purecov: inspected */
unknown's avatar
unknown committed
441 442
	my_message(ER_DIFF_GROUPS_PROC, ER(ER_DIFF_GROUPS_PROC),
                   MYF(0));                     /* purecov: inspected */
443
	goto err;				/* purecov: inspected */
unknown's avatar
unknown committed
444 445 446
      }
    }
#ifdef NOT_NEEDED
447
    else if (!group_list && procedure->flags & PROC_GROUP)
unknown's avatar
unknown committed
448
    {
unknown's avatar
unknown committed
449
      my_message(ER_NO_GROUP_FOR_PROC, MYF(0));
450
      goto err;
unknown's avatar
unknown committed
451 452 453
    }
#endif
    if (order && (procedure->flags & PROC_NO_SORT))
454
    {						/* purecov: inspected */
unknown's avatar
unknown committed
455 456
      my_message(ER_ORDER_WITH_PROC, ER(ER_ORDER_WITH_PROC),
                 MYF(0));                       /* purecov: inspected */
457
      goto err;					/* purecov: inspected */
unknown's avatar
unknown committed
458 459 460 461
    }
  }

  /* Init join struct */
462
  count_field_types(&tmp_table_param, all_fields, 0);
463
  ref_pointer_array_size= all_fields.elements*sizeof(Item*);
464
  this->group= group_list != 0;
465
  unit= unit_arg;
unknown's avatar
unknown committed
466 467

#ifdef RESTRICTED_GROUP
468
  if (sum_func_count && !group_list && (func_count || field_count))
unknown's avatar
unknown committed
469
  {
unknown's avatar
unknown committed
470
    my_message(ER_WRONG_SUM_SELECT,ER(ER_WRONG_SUM_SELECT),MYF(0));
471
    goto err;
unknown's avatar
unknown committed
472 473
  }
#endif
unknown's avatar
af  
unknown committed
474
  if (!procedure && result && result->prepare(fields_list, unit_arg))
475 476 477 478 479 480 481
    goto err;					/* purecov: inspected */

  if (select_lex->olap == ROLLUP_TYPE && rollup_init())
    goto err;
  if (alloc_func_list())
    goto err;

unknown's avatar
VIEW  
unknown committed
482
  select_lex->fix_prepare_information(thd, &conds);
483
  DBUG_RETURN(0); // All OK
484 485 486 487 488

err:
  delete procedure;				/* purecov: inspected */
  procedure= 0;
  DBUG_RETURN(-1);				/* purecov: inspected */
489
}
unknown's avatar
unknown committed
490

491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506
/*
  test if it is known for optimisation IN subquery

  SYNOPSYS
    JOIN::test_in_subselect
    where - pointer for variable in which conditions should be
            stored if subquery is known

  RETURN
    1 - known
    0 - unknown
*/

bool JOIN::test_in_subselect(Item **where)
{
  if (conds->type() == Item::FUNC_ITEM &&
507
      ((Item_func *)this->conds)->functype() == Item_func::EQ_FUNC &&
508 509 510 511 512 513 514 515 516 517 518
      ((Item_func *)conds)->arguments()[0]->type() == Item::REF_ITEM &&
      ((Item_func *)conds)->arguments()[1]->type() == Item::FIELD_ITEM)
  {
    join_tab->info= "Using index";
    *where= 0;
    return 1;
  }
  if (conds->type() == Item::COND_ITEM &&
      ((class Item_func *)this->conds)->functype() ==
      Item_func::COND_AND_FUNC)
  {
519 520 521 522
    if ((*where= remove_additional_cond(conds)))
      join_tab->info= "Using index; Using where";
    else
      join_tab->info= "Using index";
523 524 525 526 527
    return 1;
  }
  return 0;
}

528 529 530
/*
  global select optimisation.
  return 0 - success
531
         1 - error
532 533 534 535 536 537
  error code saved in field 'error'
*/
int
JOIN::optimize()
{
  DBUG_ENTER("JOIN::optimize");
unknown's avatar
unknown committed
538
  // to prevent double initialization on EXPLAIN
539 540 541
  if (optimized)
    DBUG_RETURN(0);
  optimized= 1;
unknown's avatar
unknown committed
542

543 544 545 546 547 548 549
  row_limit= ((select_distinct || order || group_list) ? HA_POS_ERROR :
	      unit->select_limit_cnt);
  /* select_limit is used to decide if we are likely to scan the whole table */
  select_limit= unit->select_limit_cnt;
  if (having || (select_options & OPTION_FOUND_ROWS))
    select_limit= HA_POS_ERROR;
  do_send_rows = (unit->select_limit_cnt) ? 1 : 0;
550
  // Ignore errors of execution if option IGNORE present
551
  if (thd->lex->ignore)
552
    thd->lex->current_select->no_error= 1;
unknown's avatar
unknown committed
553 554
#ifdef HAVE_REF_TO_FIELDS			// Not done yet
  /* Add HAVING to WHERE if possible */
555
  if (having && !group_list && !sum_func_count)
unknown's avatar
unknown committed
556 557 558
  {
    if (!conds)
    {
559 560
      conds= having;
      having= 0;
unknown's avatar
unknown committed
561 562 563
    }
    else if ((conds=new Item_cond_and(conds,having)))
    {
unknown's avatar
unknown committed
564 565 566 567
      /*
        Item_cond_and can't be fixed after creation, so we do not check
        conds->fixed
      */
unknown's avatar
unknown committed
568
      conds->fix_fields(thd, tables_list, &conds);
569
      conds->change_ref_to_fields(thd, tables_list);
570
      conds->top_level_item();
571
      having= 0;
unknown's avatar
unknown committed
572 573 574
    }
  }
#endif
unknown's avatar
unknown committed
575 576
  SELECT_LEX *sel= thd->lex->current_select;
  if (sel->first_cond_optimization)
577
  {
unknown's avatar
unknown committed
578 579 580 581 582
    /*
      The following code will allocate the new items in a permanent
      MEMROOT for prepared statements and stored procedures.
    */

unknown's avatar
unknown committed
583
    Query_arena *arena= thd->current_arena, backup;
unknown's avatar
unknown committed
584 585 586 587 588 589 590 591 592 593 594 595 596 597
    if (arena->is_conventional())
      arena= 0;                                   // For easier test
    else
      thd->set_n_backup_item_arena(arena, &backup);

    sel->first_cond_optimization= 0;

    /* Convert all outer joins to inner joins if possible */
    conds= simplify_joins(this, join_list, conds, TRUE);

    sel->prep_where= conds ? conds->copy_andor_structure(thd) : 0;

    if (arena)
      thd->restore_backup_item_arena(arena, &backup);
598 599
  }

unknown's avatar
unknown committed
600
  conds= optimize_cond(this, conds, join_list, &cond_value);   
601
  if (thd->net.report_error)
unknown's avatar
unknown committed
602
  {
unknown's avatar
unknown committed
603
    error= 1;
604
    DBUG_PRINT("error",("Error from optimize_cond"));
605
    DBUG_RETURN(1);
unknown's avatar
unknown committed
606
  }
unknown's avatar
unknown committed
607

unknown's avatar
unknown committed
608 609
  if (cond_value == Item::COND_FALSE ||
      (!unit->select_limit_cnt && !(select_options & OPTION_FOUND_ROWS)))
unknown's avatar
unknown committed
610
  {						/* Impossible cond */
611
    DBUG_PRINT("info", ("Impossible WHERE"));
612
    zero_result_cause= "Impossible WHERE";
613
    error= 0;
614
    DBUG_RETURN(0);
unknown's avatar
unknown committed
615 616 617
  }

  /* Optimize count(*), min() and max() */
618
  if (tables_list && tmp_table_param.sum_func_count && ! group_list)
unknown's avatar
unknown committed
619 620
  {
    int res;
unknown's avatar
unknown committed
621
    /*
unknown's avatar
unknown committed
622 623
      opt_sum_query() returns -1 if no rows match to the WHERE conditions,
      or 1 if all items were resolved, or 0, or an error number HA_ERR_...
unknown's avatar
unknown committed
624
    */
625
    if ((res=opt_sum_query(select_lex->leaf_tables, all_fields, conds)))
unknown's avatar
unknown committed
626
    {
unknown's avatar
unknown committed
627 628
      if (res > 1)
      {
629
        DBUG_PRINT("error",("Error from opt_sum_query"));
630
	DBUG_RETURN(1);
unknown's avatar
unknown committed
631
      }
unknown's avatar
unknown committed
632 633
      if (res < 0)
      {
634
        DBUG_PRINT("info",("No matching min/max row"));
635
	zero_result_cause= "No matching min/max row";
unknown's avatar
unknown committed
636
	error=0;
637
	DBUG_RETURN(0);
unknown's avatar
unknown committed
638
      }
639
      DBUG_PRINT("info",("Select tables optimized away"));
unknown's avatar
unknown committed
640
      zero_result_cause= "Select tables optimized away";
unknown's avatar
unknown committed
641
      tables_list= 0;				// All tables resolved
unknown's avatar
unknown committed
642 643
    }
  }
644
  if (!tables_list)
645
  {
646
    DBUG_PRINT("info",("No tables"));
647
    error= 0;
648
    DBUG_RETURN(0);
649
  }
unknown's avatar
unknown committed
650
  error= -1;					// Error is sent to client
651
  sort_by_table= get_sort_by_table(order, group_list, select_lex->leaf_tables);
unknown's avatar
unknown committed
652 653

  /* Calculate how to do the join */
654
  thd->proc_info= "statistics";
655
  if (make_join_statistics(this, select_lex->leaf_tables, conds, &keyuse) ||
656
      thd->is_fatal_error)
657 658
  {
    DBUG_PRINT("error",("Error: make_join_statistics() failed"));
unknown's avatar
unknown committed
659
    DBUG_RETURN(1);
660
  }
661

unknown's avatar
unknown committed
662 663
  /* Remove distinct if only const tables */
  select_distinct= select_distinct && (const_tables != tables);
664
  thd->proc_info= "preparing";
unknown's avatar
unknown committed
665
  if (result->initialize_tables(this))
unknown's avatar
unknown committed
666
  {
667 668
    DBUG_PRINT("error",("Error: initialize_tables() failed"));
    DBUG_RETURN(1);				// error == -1
unknown's avatar
unknown committed
669
  }
670
  if (const_table_map != found_const_table_map &&
unknown's avatar
af  
unknown committed
671 672 673 674
      !(select_options & SELECT_DESCRIBE) &&
      (!conds ||
       !(conds->used_tables() & RAND_TABLE_BIT) ||
       select_lex->master_unit() == &thd->lex->unit)) // upper level SELECT
unknown's avatar
unknown committed
675
  {
unknown's avatar
unknown committed
676
    zero_result_cause= "no matching row in const table";
677 678
    DBUG_PRINT("error",("Error: %s", zero_result_cause));
    error= 0;
679
    DBUG_RETURN(0);
unknown's avatar
unknown committed
680 681
  }
  if (!(thd->options & OPTION_BIG_SELECTS) &&
unknown's avatar
unknown committed
682
      best_read > (double) thd->variables.max_join_size &&
unknown's avatar
unknown committed
683 684
      !(select_options & SELECT_DESCRIBE))
  {						/* purecov: inspected */
685
    my_message(ER_TOO_BIG_SELECT, ER(ER_TOO_BIG_SELECT), MYF(0));
686
    error= -1;
unknown's avatar
unknown committed
687
    DBUG_RETURN(1);
unknown's avatar
unknown committed
688
  }
689
  if (const_tables && !thd->locked_tables &&
unknown's avatar
unknown committed
690
      !(select_options & SELECT_NO_UNLOCK))
691
    mysql_unlock_some_tables(thd, table, const_tables);
692
  if (!conds && outer_join)
693 694 695 696
  {
    /* Handle the case where we have an OUTER JOIN without a WHERE */
    conds=new Item_int((longlong) 1,1);	// Always true
  }
unknown's avatar
unknown committed
697 698
  select= make_select(*table, const_table_map,
                      const_table_map, conds, 1, &error);
unknown's avatar
unknown committed
699
  if (error)
unknown's avatar
unknown committed
700 701
  {						/* purecov: inspected */
    error= -1;					/* purecov: inspected */
702
    DBUG_PRINT("error",("Error: make_select() failed"));
unknown's avatar
unknown committed
703
    DBUG_RETURN(1);
unknown's avatar
unknown committed
704
  }
705 706 707

  make_outerjoin_info(this);

unknown's avatar
unknown committed
708 709 710 711 712 713 714 715 716 717
  /*
    Among the equal fields belonging to the same multiple equality
    choose the one that is to be retrieved first and substitute
    all references to these in where condition for a reference for
    the selected field.
  */
  if (conds)
  {
    conds= substitute_for_best_equal_field(conds, cond_equal, map2table);
    conds->update_used_tables();
unknown's avatar
unknown committed
718
    DBUG_EXECUTE("where", print_where(conds, "after substitute_best_equal"););
unknown's avatar
unknown committed
719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734
  }
  /*
    Permorm the the optimization on fields evaluation mentioned above
    for all on expressions.
  */ 
  for (JOIN_TAB *tab= join_tab + const_tables; tab < join_tab + tables ; tab++)
  {
    if (*tab->on_expr_ref)
    {
      *tab->on_expr_ref= substitute_for_best_equal_field(*tab->on_expr_ref,
                                                         tab->cond_equal,
                                                         map2table);
      (*tab->on_expr_ref)->update_used_tables();
    }
  }

735
  if (make_join_select(this, select, conds))
unknown's avatar
unknown committed
736
  {
737 738
    zero_result_cause=
      "Impossible WHERE noticed after reading const tables";
739
    DBUG_RETURN(0);				// error == 0
unknown's avatar
unknown committed
740 741 742 743 744
  }

  error= -1;					/* if goto err */

  /* Optimize distinct away if possible */
unknown's avatar
unknown committed
745 746
  {
    ORDER *org_order= order;
747
    order=remove_const(this, order,conds,1, &simple_order);
unknown's avatar
unknown committed
748 749 750 751 752 753 754
    /*
      If we are using ORDER BY NULL or ORDER BY const_expression,
      return result in any order (even if we are using a GROUP BY)
    */
    if (!order && org_order)
      skip_sort_order= 1;
  }
755
  if (group_list || tmp_table_param.sum_func_count)
unknown's avatar
unknown committed
756 757 758 759
  {
    if (! hidden_group_fields)
      select_distinct=0;
  }
unknown's avatar
unknown committed
760
  else if (select_distinct && tables - const_tables == 1)
unknown's avatar
unknown committed
761
  {
762 763 764 765 766 767 768 769 770 771 772 773 774 775 776
    /*
      We are only using one table. In this case we change DISTINCT to a
      GROUP BY query if:
      - The GROUP BY can be done through indexes (no sort) and the ORDER
        BY only uses selected fields.
	(In this case we can later optimize away GROUP BY and ORDER BY)
      - We are scanning the whole table without LIMIT
        This can happen if:
        - We are using CALC_FOUND_ROWS
        - We are using an ORDER BY that can't be optimized away.

      We don't want to use this optimization when we are using LIMIT
      because in this case we can just create a temporary table that
      holds LIMIT rows and stop when this table is full.
    */
unknown's avatar
unknown committed
777
    JOIN_TAB *tab= &join_tab[const_tables];
778 779 780
    bool all_order_fields_used;
    if (order)
      skip_sort_order= test_if_skip_sort_order(tab, order, select_limit, 1);
unknown's avatar
unknown committed
781 782
    if ((group_list=create_distinct_group(thd, order, fields_list,
				          &all_order_fields_used)))
783 784
    {
      bool skip_group= (skip_sort_order &&
unknown's avatar
unknown committed
785
			test_if_skip_sort_order(tab, group_list, select_limit,
786 787 788 789 790 791 792 793 794
						1) != 0);
      if ((skip_group && all_order_fields_used) ||
	  select_limit == HA_POS_ERROR ||
	  (order && !skip_sort_order))
      {
	/*  Change DISTINCT to GROUP BY */
	select_distinct= 0;
	no_order= !order;
	if (all_order_fields_used)
795 796 797 798 799 800
	{
	  if (order && skip_sort_order)
	  {
	    /*
	      Force MySQL to read the table in sorted order to get result in
	      ORDER BY order.
unknown's avatar
unknown committed
801
	    */
unknown's avatar
unknown committed
802
	    tmp_table_param.quick_group=0;
803
	  }
804
	  order=0;
unknown's avatar
unknown committed
805
        }
unknown's avatar
unknown committed
806
	group=1;				// For end_write_group
807 808
      }
      else
unknown's avatar
unknown committed
809
	group_list= 0;
unknown's avatar
unknown committed
810
    }
811
    else if (thd->is_fatal_error)			// End of memory
unknown's avatar
unknown committed
812
      DBUG_RETURN(1);
unknown's avatar
unknown committed
813
  }
814
  simple_group= 0;
815 816 817
  group_list= remove_const(this, group_list, conds,
                           rollup.state == ROLLUP::STATE_NONE,
                           &simple_group);
818
  if (!group_list && group)
unknown's avatar
unknown committed
819 820 821 822 823
  {
    order=0;					// The output has only one row
    simple_order=1;
  }

824 825
  calc_group_buffer(this, group_list);
  send_group_parts= tmp_table_param.group_parts; /* Save org parts */
unknown's avatar
unknown committed
826 827
  if (procedure && procedure->group)
  {
828
    group_list= procedure->group= remove_const(this, procedure->group, conds,
829
					       1, &simple_group);
830
    calc_group_buffer(this, group_list);
unknown's avatar
unknown committed
831 832
  }

833 834
  if (test_if_subpart(group_list, order) ||
      (!group_list && tmp_table_param.sum_func_count))
unknown's avatar
unknown committed
835 836
    order=0;

unknown's avatar
unknown committed
837
  // Can't use sort on head table if using row cache
838
  if (full_join)
unknown's avatar
unknown committed
839
  {
840
    if (group_list)
unknown's avatar
unknown committed
841 842 843 844 845
      simple_group=0;
    if (order)
      simple_order=0;
  }

846 847 848 849 850 851 852 853 854
  /*
    Check if we need to create a temporary table.
    This has to be done if all tables are not already read (const tables)
    and one of the following conditions holds:
    - We are using DISTINCT (simple distinct's are already optimized away)
    - We are using an ORDER BY or GROUP BY on fields not in the first table
    - We are using different ORDER BY and GROUP BY orders
    - The user wants us to buffer the result.
  */
855
  need_tmp= (const_tables != tables &&
unknown's avatar
unknown committed
856
	     ((select_distinct || !simple_order || !simple_group) ||
unknown's avatar
unknown committed
857
	      (group_list && order) ||
858
	      test(select_options & OPTION_BUFFER_RESULT)));
unknown's avatar
unknown committed
859

unknown's avatar
unknown committed
860
  // No cache for MATCH
861
  make_join_readinfo(this,
unknown's avatar
unknown committed
862
		     (select_options & (SELECT_DESCRIBE |
863
					SELECT_NO_JOIN_CACHE)) |
unknown's avatar
unknown committed
864
		     (select_lex->ftfunc_list->elements ?
865
		      SELECT_NO_JOIN_CACHE : 0));
unknown's avatar
unknown committed
866

867 868 869 870
  /* Perform FULLTEXT search before all regular searches */
  if (!(select_options & SELECT_DESCRIBE))
    init_ftfuncs(thd, select_lex, test(order));

871 872 873
  /*
    is this simple IN subquery?
  */
874
  if (!group_list && !order &&
875
      unit->item && unit->item->substype() == Item_subselect::IN_SUBS &&
876
      tables == 1 && conds &&
877 878
      !unit->first_select()->next_select())
  {
879
    if (!having)
880
    {
881
      Item *where= 0;
882 883
      if (join_tab[0].type == JT_EQ_REF &&
	  join_tab[0].ref.items[0]->name == in_left_expr_name)
884
      {
885 886
	if (test_in_subselect(&where))
	{
887
	  join_tab[0].type= JT_UNIQUE_SUBQUERY;
888 889
	  error= 0;
	  DBUG_RETURN(unit->item->
890 891 892 893 894
		      change_engine(new
				    subselect_uniquesubquery_engine(thd,
								    join_tab,
								    unit->item,
								    where)));
895
	}
896
      }
897 898
      else if (join_tab[0].type == JT_REF &&
	       join_tab[0].ref.items[0]->name == in_left_expr_name)
899
      {
900 901
	if (test_in_subselect(&where))
	{
902
	  join_tab[0].type= JT_INDEX_SUBQUERY;
903 904
	  error= 0;
	  DBUG_RETURN(unit->item->
905 906 907 908 909 910
		      change_engine(new
				    subselect_indexsubquery_engine(thd,
								   join_tab,
								   unit->item,
								   where,
								   0)));
911
	}
912
      }
913
    } else if (join_tab[0].type == JT_REF_OR_NULL &&
914
	       join_tab[0].ref.items[0]->name == in_left_expr_name &&
915 916 917 918
	       having->type() == Item::FUNC_ITEM &&
	       ((Item_func *) having)->functype() ==
	       Item_func::ISNOTNULLTEST_FUNC)
    {
919
      join_tab[0].type= JT_INDEX_SUBQUERY;
920
      error= 0;
921 922 923 924 925

      if ((conds= remove_additional_cond(conds)))
	join_tab->info= "Using index; Using where";
      else
	join_tab->info= "Using index";
926

927
      DBUG_RETURN(unit->item->
928 929 930 931 932
		  change_engine(new subselect_indexsubquery_engine(thd,
								   join_tab,
								   unit->item,
								   conds,
								   1)));
933
    }
934

935
  }
936 937 938 939 940 941 942
  /*
    Need to tell Innobase that to play it safe, it should fetch all
    columns of the tables: this is because MySQL may build row
    pointers for the rows, and for all columns of the primary key the
    field->query_id has not necessarily been set to thd->query_id by
    MySQL.
  */
unknown's avatar
unknown committed
943 944

#ifdef HAVE_INNOBASE_DB
945
  if (need_tmp || select_distinct || group_list || order)
unknown's avatar
unknown committed
946
  {
947
    for (uint i_h = const_tables; i_h < tables; i_h++)
unknown's avatar
unknown committed
948
    {
949
      TABLE* table_h = join_tab[i_h].table;
unknown's avatar
af  
unknown committed
950
      table_h->file->extra(HA_EXTRA_RETRIEVE_PRIMARY_KEY);
unknown's avatar
unknown committed
951 952 953 954
    }
  }
#endif

955
  DBUG_EXECUTE("info",TEST_join(this););
unknown's avatar
unknown committed
956

unknown's avatar
unknown committed
957
  if (const_tables != tables)
unknown's avatar
unknown committed
958
  {
unknown's avatar
unknown committed
959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984
    /*
      Because filesort always does a full table scan or a quick range scan
      we must add the removed reference to the select for the table.
      We only need to do this when we have a simple_order or simple_group
      as in other cases the join is done before the sort.
    */
    if ((order || group_list) &&
        join_tab[const_tables].type != JT_ALL &&
        join_tab[const_tables].type != JT_FT &&
        join_tab[const_tables].type != JT_REF_OR_NULL &&
        (order && simple_order || group_list && simple_group))
    {
      if (add_ref_to_table_cond(thd,&join_tab[const_tables]))
        DBUG_RETURN(1);
    }
    
    if (!(select_options & SELECT_BIG_RESULT) &&
        ((group_list &&
          (!simple_group ||
           !test_if_skip_sort_order(&join_tab[const_tables], group_list,
                                    unit->select_limit_cnt, 0))) ||
         select_distinct) &&
        tmp_table_param.quick_group && !procedure)
    {
      need_tmp=1; simple_order=simple_group=0;	// Force tmp table without sort
    }
unknown's avatar
unknown committed
985
  }
986

unknown's avatar
unknown committed
987
  tmp_having= having;
988
  if (select_options & SELECT_DESCRIBE)
989 990
  {
    error= 0;
991
    DBUG_RETURN(0);
992
  }
993 994 995 996 997 998 999 1000 1001
  having= 0;

  /* Create a tmp table if distinct or if the sort is too complicated */
  if (need_tmp)
  {
    DBUG_PRINT("info",("Creating tmp table"));
    thd->proc_info="Creating tmp table";

    init_items_ref_array();
1002

1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013
    tmp_table_param.hidden_field_count= (all_fields.elements -
					 fields_list.elements);
    if (!(exec_tmp_table1 =
	  create_tmp_table(thd, &tmp_table_param, all_fields,
			   ((!simple_group && !procedure &&
			     !(test_flags & TEST_NO_KEY_GROUP)) ?
			    group_list : (ORDER*) 0),
			   group_list ? 0 : select_distinct,
			   group_list && simple_group,
			   select_options,
			   (order == 0 || skip_sort_order) ? select_limit :
1014 1015
			   HA_POS_ERROR,
			   (char *) "")))
1016
      DBUG_RETURN(1);
1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027

    /*
      We don't have to store rows in temp table that doesn't match HAVING if:
      - we are sorting the table and writing complete group rows to the
        temp table.
      - We are using DISTINCT without resolving the distinct as a GROUP BY
        on all columns.
      
      If having is not handled here, it will be checked before the row
      is sent to the client.
    */    
unknown's avatar
unknown committed
1028
    if (tmp_having && 
1029 1030 1031 1032 1033 1034 1035 1036
	(sort_and_group || (exec_tmp_table1->distinct && !group_list)))
      having= tmp_having;

    /* if group or order on first table, sort first */
    if (group_list && simple_group)
    {
      DBUG_PRINT("info",("Sorting for group"));
      thd->proc_info="Sorting for group";
1037
      if (create_sort_index(thd, this, group_list,
1038
			    HA_POS_ERROR, HA_POS_ERROR) ||
1039
	  alloc_group_fields(this, group_list) ||
1040 1041
          make_sum_func_list(all_fields, fields_list, 1) ||
          setup_sum_funcs(thd, sum_funcs))
1042 1043 1044 1045 1046
	DBUG_RETURN(1);
      group_list=0;
    }
    else
    {
1047 1048
      if (make_sum_func_list(all_fields, fields_list, 0) ||
          setup_sum_funcs(thd, sum_funcs))
1049 1050 1051 1052 1053
	DBUG_RETURN(1);
      if (!group_list && ! exec_tmp_table1->distinct && order && simple_order)
      {
	DBUG_PRINT("info",("Sorting for order"));
	thd->proc_info="Sorting for order";
1054
	if (create_sort_index(thd, this, order,
1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069
                              HA_POS_ERROR, HA_POS_ERROR))
	  DBUG_RETURN(1);
	order=0;
      }
    }
    
    /*
      Optimize distinct when used on some of the tables
      SELECT DISTINCT t1.a FROM t1,t2 WHERE t1.b=t2.b
      In this case we can stop scanning t2 when we have found one t1.a
    */

    if (exec_tmp_table1->distinct)
    {
      table_map used_tables= thd->used_tables;
1070
      JOIN_TAB *last_join_tab= join_tab+tables-1;
1071 1072
      do
      {
1073
	if (used_tables & last_join_tab->table->map)
1074
	  break;
1075 1076
	last_join_tab->not_used_in_distinct=1;
      } while (last_join_tab-- != join_tab);
1077 1078 1079 1080
      /* Optimize "select distinct b from t1 order by key_part_1 limit #" */
      if (order && skip_sort_order)
      {
 	/* Should always succeed */
1081
	if (test_if_skip_sort_order(&join_tab[const_tables],
1082 1083 1084 1085 1086
				    order, unit->select_limit_cnt, 0))
	  order=0;
      }
    }
    
1087
    if (thd->lex->subqueries)
1088 1089 1090
    {
      if (!(tmp_join= (JOIN*)thd->alloc(sizeof(JOIN))))
	DBUG_RETURN(-1);
1091
      error= 0;				// Ensure that tmp_join.error= 0
1092 1093 1094 1095
      restore_tmp();
    }
  }

1096
  error= 0;
1097 1098 1099
  DBUG_RETURN(0);
}

1100

1101
/*
1102
  Restore values in temporary join
1103
*/
1104
void JOIN::restore_tmp()
1105
{
1106
  memcpy(tmp_join, this, (size_t) sizeof(JOIN));
1107 1108
}

1109

1110 1111 1112 1113
int
JOIN::reinit()
{
  DBUG_ENTER("JOIN::reinit");
unknown's avatar
VIEW  
unknown committed
1114

unknown's avatar
unknown committed
1115
  first_record= 0;
unknown's avatar
unknown committed
1116

1117 1118 1119 1120 1121
  if (exec_tmp_table1)
  {
    exec_tmp_table1->file->extra(HA_EXTRA_RESET_STATE);
    exec_tmp_table1->file->delete_all_rows();
    free_io_cache(exec_tmp_table1);
unknown's avatar
unknown committed
1122
    filesort_free_buffers(exec_tmp_table1);
1123 1124 1125 1126 1127 1128
  }
  if (exec_tmp_table2)
  {
    exec_tmp_table2->file->extra(HA_EXTRA_RESET_STATE);
    exec_tmp_table2->file->delete_all_rows();
    free_io_cache(exec_tmp_table2);
unknown's avatar
unknown committed
1129
    filesort_free_buffers(exec_tmp_table2);
1130 1131
  }
  if (items0)
1132
    set_items_ref_array(items0);
1133

1134 1135 1136
  if (join_tab_save)
    memcpy(join_tab, join_tab_save, sizeof(JOIN_TAB) * tables);

1137 1138 1139
  if (tmp_join)
    restore_tmp();

1140
  /* Reset of sum functions */
unknown's avatar
af  
unknown committed
1141 1142 1143 1144 1145 1146 1147
  if (sum_funcs)
  {
    Item_sum *func, **func_ptr= sum_funcs;
    while ((func= *(func_ptr++)))
      func->clear();
  }

1148 1149 1150
  DBUG_RETURN(0);
}

1151 1152 1153 1154

bool
JOIN::save_join_tab()
{
unknown's avatar
unknown committed
1155
  if (!join_tab_save && select_lex->master_unit()->uncacheable)
1156
  {
unknown's avatar
unknown committed
1157 1158
    if (!(join_tab_save= (JOIN_TAB*)thd->memdup((gptr) join_tab,
						sizeof(JOIN_TAB) * tables)))
1159 1160 1161 1162 1163 1164
      return 1;
  }
  return 0;
}


1165
/*
1166
  Exec select
1167 1168 1169 1170 1171 1172
*/
void
JOIN::exec()
{
  int      tmp_error;
  DBUG_ENTER("JOIN::exec");
1173

1174
  error= 0;
unknown's avatar
unknown committed
1175 1176 1177 1178
  if (procedure)
  {
    if (procedure->change_columns(fields_list) ||
	result->prepare(fields_list, unit))
1179 1180
    {
      thd->limit_found_rows= thd->examined_row_count= 0;
unknown's avatar
unknown committed
1181
      DBUG_VOID_RETURN;
1182
    }
unknown's avatar
unknown committed
1183
  }
1184
  (void) result->prepare2(); // Currently, this cannot fail.
1185

unknown's avatar
unknown committed
1186
  if (!tables_list)
1187 1188
  {                                           // Only test of functions
    if (select_options & SELECT_DESCRIBE)
unknown's avatar
af  
unknown committed
1189
      select_describe(this, FALSE, FALSE, FALSE,
unknown's avatar
unknown committed
1190
		      (zero_result_cause?zero_result_cause:"No tables used"));
1191 1192
    else
    {
1193 1194
      result->send_fields(fields_list,
                          Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF);
1195 1196
      if (!having || having->val_int())
      {
1197 1198 1199
	if (do_send_rows && (procedure ? (procedure->send_row(fields_list) ||
                                          procedure->end_of_records())
                                       : result->send_data(fields_list)))
unknown's avatar
unknown committed
1200
	  error= 1;
1201
	else
1202
	{
unknown's avatar
unknown committed
1203
	  error= (int) result->send_eof();
1204 1205
	  send_records=1;
	}
1206 1207
      }
      else
1208
	error=(int) result->send_eof();
1209
    }
1210 1211 1212
    /* Single select (without union and limit) always returns 1 row */
    thd->limit_found_rows= 1;
    thd->examined_row_count= 0;
1213 1214
    DBUG_VOID_RETURN;
  }
1215
  thd->limit_found_rows= thd->examined_row_count= 0;
1216 1217 1218

  if (zero_result_cause)
  {
1219
    (void) return_zero_rows(this, result, select_lex->leaf_tables, fields_list,
unknown's avatar
af  
unknown committed
1220
			    send_row_on_empty_set(),
unknown's avatar
unknown committed
1221 1222
			    select_options,
			    zero_result_cause,
1223
			    having, procedure,
unknown's avatar
unknown committed
1224
			    unit);
1225 1226 1227
    DBUG_VOID_RETURN;
  }

unknown's avatar
unknown committed
1228 1229
  if (select_options & SELECT_DESCRIBE)
  {
unknown's avatar
unknown committed
1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244
    /*
      Check if we managed to optimize ORDER BY away and don't use temporary
      table to resolve ORDER BY: in that case, we only may need to do
      filesort for GROUP BY.
    */
    if (!order && !no_order && (!skip_sort_order || !need_tmp))
    {
      /*
	Reset 'order' to 'group_list' and reinit variables describing
	'order'
      */
      order= group_list;
      simple_order= simple_group;
      skip_sort_order= 0;
    }
unknown's avatar
unknown committed
1245
    if (order &&
1246
	(const_tables == tables ||
unknown's avatar
unknown committed
1247
 	 ((simple_order || skip_sort_order) &&
1248
	  test_if_skip_sort_order(&join_tab[const_tables], order,
1249
				  select_limit, 0))))
unknown's avatar
unknown committed
1250
      order=0;
1251
    having= tmp_having;
1252
    select_describe(this, need_tmp,
1253
		    order != 0 && !skip_sort_order,
unknown's avatar
unknown committed
1254
		    select_distinct);
1255
    DBUG_VOID_RETURN;
unknown's avatar
unknown committed
1256 1257
  }

1258 1259 1260 1261
  JOIN *curr_join= this;
  List<Item> *curr_all_fields= &all_fields;
  List<Item> *curr_fields_list= &fields_list;
  TABLE *curr_tmp_table= 0;
1262

1263 1264 1265 1266 1267 1268
  if ((curr_join->select_lex->options & OPTION_SCHEMA_TABLE) &&
      get_schema_tables_result(curr_join))
  {
    DBUG_VOID_RETURN;
  }

unknown's avatar
unknown committed
1269 1270 1271
  /* Create a tmp table if distinct or if the sort is too complicated */
  if (need_tmp)
  {
1272 1273 1274
    if (tmp_join)
      curr_join= tmp_join;
    curr_tmp_table= exec_tmp_table1;
unknown's avatar
unknown committed
1275 1276

    /* Copy data to the temporary table */
1277
    thd->proc_info= "Copying to tmp table";
unknown's avatar
unknown committed
1278
    DBUG_PRINT("info", ("%s", thd->proc_info));
1279
    if ((tmp_error= do_select(curr_join, (List<Item> *) 0, curr_tmp_table, 0)))
1280
    {
1281 1282
      error= tmp_error;
      DBUG_VOID_RETURN;
1283
    }
1284 1285 1286 1287 1288
    curr_tmp_table->file->info(HA_STATUS_VARIABLE);
    
    if (curr_join->having)
      curr_join->having= curr_join->tmp_having= 0; // Allready done
    
unknown's avatar
unknown committed
1289
    /* Change sum_fields reference to calculated fields in tmp_table */
1290 1291
    curr_join->all_fields= *curr_all_fields;
    if (!items1)
unknown's avatar
unknown committed
1292
    {
1293 1294 1295
      items1= items0 + all_fields.elements;
      if (sort_and_group || curr_tmp_table->group)
      {
1296
	if (change_to_use_tmp_fields(thd, items1,
1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313
				     tmp_fields_list1, tmp_all_fields1,
				     fields_list.elements, all_fields))
	  DBUG_VOID_RETURN;
      }
      else
      {
	if (change_refs_to_tmp_fields(thd, items1,
				      tmp_fields_list1, tmp_all_fields1,
				      fields_list.elements, all_fields))
	  DBUG_VOID_RETURN;
      }
      curr_join->tmp_all_fields1= tmp_all_fields1;
      curr_join->tmp_fields_list1= tmp_fields_list1;
      curr_join->items1= items1;
    }
    curr_all_fields= &tmp_all_fields1;
    curr_fields_list= &tmp_fields_list1;
unknown's avatar
unknown committed
1314
    curr_join->set_items_ref_array(items1);
1315 1316 1317 1318 1319 1320 1321 1322
    
    if (sort_and_group || curr_tmp_table->group)
    {
      curr_join->tmp_table_param.field_count+= 
	curr_join->tmp_table_param.sum_func_count+
	curr_join->tmp_table_param.func_count;
      curr_join->tmp_table_param.sum_func_count= 
	curr_join->tmp_table_param.func_count= 0;
unknown's avatar
unknown committed
1323 1324 1325
    }
    else
    {
1326 1327 1328
      curr_join->tmp_table_param.field_count+= 
	curr_join->tmp_table_param.func_count;
      curr_join->tmp_table_param.func_count= 0;
unknown's avatar
unknown committed
1329
    }
1330 1331
    
    // procedure can't be used inside subselect => we do nothing special for it
unknown's avatar
unknown committed
1332 1333
    if (procedure)
      procedure->update_refs();
1334 1335
    
    if (curr_tmp_table->group)
unknown's avatar
unknown committed
1336
    {						// Already grouped
unknown's avatar
unknown committed
1337
      if (!curr_join->order && !curr_join->no_order && !skip_sort_order)
1338 1339
	curr_join->order= curr_join->group_list;  /* order by group */
      curr_join->group_list= 0;
unknown's avatar
unknown committed
1340
    }
1341
    
unknown's avatar
unknown committed
1342
    /*
1343 1344 1345 1346 1347
      If we have different sort & group then we must sort the data by group
      and copy it to another tmp table
      This code is also used if we are using distinct something
      we haven't been able to store in the temporary table yet
      like SEC_TO_TIME(SUM(...)).
unknown's avatar
unknown committed
1348 1349
    */

1350 1351 1352 1353 1354
    if (curr_join->group_list && (!test_if_subpart(curr_join->group_list,
						   curr_join->order) || 
				  curr_join->select_distinct) ||
	(curr_join->select_distinct &&
	 curr_join->tmp_table_param.using_indirect_summary_function))
unknown's avatar
unknown committed
1355 1356
    {					/* Must copy to another table */
      DBUG_PRINT("info",("Creating group table"));
1357
      
unknown's avatar
unknown committed
1358
      /* Free first data from old join */
1359
      curr_join->join_free(0);
1360
      if (make_simple_join(curr_join, curr_tmp_table))
unknown's avatar
unknown committed
1361
	DBUG_VOID_RETURN;
1362
      calc_group_buffer(curr_join, group_list);
1363 1364
      count_field_types(&curr_join->tmp_table_param,
			curr_join->tmp_all_fields1,
1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383
			curr_join->select_distinct && !curr_join->group_list);
      curr_join->tmp_table_param.hidden_field_count= 
	(curr_join->tmp_all_fields1.elements-
	 curr_join->tmp_fields_list1.elements);
      
      
      if (exec_tmp_table2)
	curr_tmp_table= exec_tmp_table2;
      else
      {
	/* group data to new table */
	if (!(curr_tmp_table=
	      exec_tmp_table2= create_tmp_table(thd,
						&curr_join->tmp_table_param,
						*curr_all_fields,
						(ORDER*) 0,
						curr_join->select_distinct && 
						!curr_join->group_list,
						1, curr_join->select_options,
1384 1385
						HA_POS_ERROR,
						(char *) "")))
1386 1387 1388
	  DBUG_VOID_RETURN;
	curr_join->exec_tmp_table2= exec_tmp_table2;
      }
1389
      if (curr_join->group_list)
unknown's avatar
unknown committed
1390
      {
1391
	thd->proc_info= "Creating sort index";
1392 1393 1394 1395
	if (curr_join->join_tab == join_tab && save_join_tab())
	{
	  DBUG_VOID_RETURN;
	}
1396
	if (create_sort_index(thd, curr_join, curr_join->group_list,
1397
			      HA_POS_ERROR, HA_POS_ERROR) ||
1398
	    make_group_fields(this, curr_join))
unknown's avatar
unknown committed
1399
	{
1400
	  DBUG_VOID_RETURN;
unknown's avatar
unknown committed
1401 1402
	}
      }
1403
      
unknown's avatar
unknown committed
1404
      thd->proc_info="Copying to group table";
unknown's avatar
unknown committed
1405
      DBUG_PRINT("info", ("%s", thd->proc_info));
1406
      tmp_error= -1;
1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420
      if (curr_join != this)
      {
	if (sum_funcs2)
	{
	  curr_join->sum_funcs= sum_funcs2;
	  curr_join->sum_funcs_end= sum_funcs_end2; 
	}
	else
	{
	  curr_join->alloc_func_list();
	  sum_funcs2= curr_join->sum_funcs;
	  sum_funcs_end2= curr_join->sum_funcs_end;
	}
      }
1421
      if (curr_join->make_sum_func_list(*curr_all_fields, *curr_fields_list,
1422 1423 1424 1425
					1, TRUE))
        DBUG_VOID_RETURN;
      curr_join->group_list= 0;
      if (setup_sum_funcs(curr_join->thd, curr_join->sum_funcs) ||
1426 1427
	  (tmp_error= do_select(curr_join, (List<Item> *) 0, curr_tmp_table,
				0)))
unknown's avatar
unknown committed
1428
      {
1429
	error= tmp_error;
1430
	DBUG_VOID_RETURN;
unknown's avatar
unknown committed
1431
      }
1432 1433 1434 1435 1436 1437 1438 1439
      end_read_record(&curr_join->join_tab->read_record);
      curr_join->const_tables= curr_join->tables; // Mark free for join_free()
      curr_join->join_tab[0].table= 0;           // Table is freed
      
      // No sum funcs anymore
      if (!items2)
      {
	items2= items1 + all_fields.elements;
1440
	if (change_to_use_tmp_fields(thd, items2,
1441 1442 1443 1444 1445 1446 1447 1448
				     tmp_fields_list2, tmp_all_fields2, 
				     fields_list.elements, tmp_all_fields1))
	  DBUG_VOID_RETURN;
	curr_join->tmp_fields_list2= tmp_fields_list2;
	curr_join->tmp_all_fields2= tmp_all_fields2;
      }
      curr_fields_list= &curr_join->tmp_fields_list2;
      curr_all_fields= &curr_join->tmp_all_fields2;
unknown's avatar
unknown committed
1449
      curr_join->set_items_ref_array(items2);
1450 1451 1452 1453 1454 1455 1456
      curr_join->tmp_table_param.field_count+= 
	curr_join->tmp_table_param.sum_func_count;
      curr_join->tmp_table_param.sum_func_count= 0;
    }
    if (curr_tmp_table->distinct)
      curr_join->select_distinct=0;		/* Each row is unique */
    
1457
    curr_join->join_free(0);			/* Free quick selects */
1458
    if (curr_join->select_distinct && ! curr_join->group_list)
unknown's avatar
unknown committed
1459 1460
    {
      thd->proc_info="Removing duplicates";
1461 1462 1463
      if (curr_join->tmp_having)
	curr_join->tmp_having->update_used_tables();
      if (remove_duplicates(curr_join, curr_tmp_table,
unknown's avatar
unknown committed
1464
			    *curr_fields_list, curr_join->tmp_having))
1465
	DBUG_VOID_RETURN;
1466 1467
      curr_join->tmp_having=0;
      curr_join->select_distinct=0;
unknown's avatar
unknown committed
1468
    }
1469 1470
    curr_tmp_table->reginfo.lock_type= TL_UNLOCK;
    if (make_simple_join(curr_join, curr_tmp_table))
1471
      DBUG_VOID_RETURN;
1472 1473 1474
    calc_group_buffer(curr_join, curr_join->group_list);
    count_field_types(&curr_join->tmp_table_param, *curr_all_fields, 0);
    
unknown's avatar
unknown committed
1475 1476
  }
  if (procedure)
1477 1478 1479
    count_field_types(&curr_join->tmp_table_param, *curr_all_fields, 0);
  
  if (curr_join->group || curr_join->tmp_table_param.sum_func_count ||
unknown's avatar
unknown committed
1480 1481
      (procedure && (procedure->flags & PROC_GROUP)))
  {
1482 1483 1484 1485
    if (make_group_fields(this, curr_join))
    {
      DBUG_VOID_RETURN;
    }
1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509
    if (!items3)
    {
      if (!items0)
	init_items_ref_array();
      items3= ref_pointer_array + (all_fields.elements*4);
      setup_copy_fields(thd, &curr_join->tmp_table_param,
			items3, tmp_fields_list3, tmp_all_fields3,
			curr_fields_list->elements, *curr_all_fields);
      tmp_table_param.save_copy_funcs= curr_join->tmp_table_param.copy_funcs;
      tmp_table_param.save_copy_field= curr_join->tmp_table_param.copy_field;
      tmp_table_param.save_copy_field_end=
	curr_join->tmp_table_param.copy_field_end;
      curr_join->tmp_all_fields3= tmp_all_fields3;
      curr_join->tmp_fields_list3= tmp_fields_list3;
    }
    else
    {
      curr_join->tmp_table_param.copy_funcs= tmp_table_param.save_copy_funcs;
      curr_join->tmp_table_param.copy_field= tmp_table_param.save_copy_field;
      curr_join->tmp_table_param.copy_field_end=
	tmp_table_param.save_copy_field_end;
    }
    curr_fields_list= &tmp_fields_list3;
    curr_all_fields= &tmp_all_fields3;
unknown's avatar
unknown committed
1510
    curr_join->set_items_ref_array(items3);
1511

1512
    if (curr_join->make_sum_func_list(*curr_all_fields, *curr_fields_list,
1513 1514 1515
				      1, TRUE) || 
        setup_sum_funcs(curr_join->thd, curr_join->sum_funcs) ||
        thd->is_fatal_error)
1516
      DBUG_VOID_RETURN;
unknown's avatar
unknown committed
1517
  }
1518
  if (curr_join->group_list || curr_join->order)
unknown's avatar
unknown committed
1519 1520 1521 1522
  {
    DBUG_PRINT("info",("Sorting for send_fields"));
    thd->proc_info="Sorting result";
    /* If we have already done the group, add HAVING to sorted table */
1523 1524
    if (curr_join->tmp_having && ! curr_join->group_list && 
	! curr_join->sort_and_group)
unknown's avatar
unknown committed
1525
    {
1526 1527
      // Some tables may have been const
      curr_join->tmp_having->update_used_tables();
1528 1529 1530
      JOIN_TAB *curr_table= &curr_join->join_tab[curr_join->const_tables];
      table_map used_tables= (curr_join->const_table_map |
			      curr_table->table->map);
unknown's avatar
unknown committed
1531

1532 1533
      Item* sort_table_cond= make_cond_for_table(curr_join->tmp_having,
						 used_tables,
1534
						 used_tables);
unknown's avatar
unknown committed
1535 1536
      if (sort_table_cond)
      {
1537 1538
	if (!curr_table->select)
	  if (!(curr_table->select= new SQL_SELECT))
1539
	    DBUG_VOID_RETURN;
1540 1541
	if (!curr_table->select->cond)
	  curr_table->select->cond= sort_table_cond;
unknown's avatar
unknown committed
1542
	else					// This should never happen
unknown's avatar
af  
unknown committed
1543
	{
1544
	  if (!(curr_table->select->cond=
unknown's avatar
af  
unknown committed
1545 1546
		new Item_cond_and(curr_table->select->cond,
				  sort_table_cond)))
1547
	    DBUG_VOID_RETURN;
unknown's avatar
af  
unknown committed
1548 1549 1550 1551 1552 1553
	  /*
	    Item_cond_and do not need fix_fields for execution, its parameters
	    are fixed or do not need fix_fields, too
	  */
	  curr_table->select->cond->quick_fix_field();
	}
1554
	curr_table->select_cond= curr_table->select->cond;
1555 1556
	curr_table->select_cond->top_level_item();
	DBUG_EXECUTE("where",print_where(curr_table->select->cond,
unknown's avatar
unknown committed
1557
					 "select and having"););
1558 1559 1560
	curr_join->tmp_having= make_cond_for_table(curr_join->tmp_having,
						   ~ (table_map) 0,
						   ~used_tables);
unknown's avatar
unknown committed
1561 1562 1563
	DBUG_EXECUTE("where",print_where(conds,"having after sort"););
      }
    }
unknown's avatar
unknown committed
1564
    {
unknown's avatar
unknown committed
1565
      if (group)
1566
	curr_join->select_limit= HA_POS_ERROR;
unknown's avatar
unknown committed
1567
      else
unknown's avatar
unknown committed
1568
      {
unknown's avatar
unknown committed
1569 1570 1571 1572
	/*
	  We can abort sorting after thd->select_limit rows if we there is no
	  WHERE clause for any tables after the sorted one.
	*/
1573
	JOIN_TAB *curr_table= &curr_join->join_tab[curr_join->const_tables+1];
1574
	JOIN_TAB *end_table= &curr_join->join_tab[curr_join->tables];
1575
	for (; curr_table < end_table ; curr_table++)
unknown's avatar
unknown committed
1576
	{
unknown's avatar
unknown committed
1577 1578 1579 1580
	  /*
	    table->keyuse is set in the case there was an original WHERE clause
	    on the table that was optimized away.
	  */
1581
	  if (curr_table->select_cond ||
1582
	      (curr_table->keyuse && !curr_table->first_inner))
unknown's avatar
unknown committed
1583 1584
	  {
	    /* We have to sort all rows */
1585
	    curr_join->select_limit= HA_POS_ERROR;
unknown's avatar
unknown committed
1586 1587
	    break;
	  }
unknown's avatar
unknown committed
1588 1589
	}
      }
1590 1591 1592 1593
      if (curr_join->join_tab == join_tab && save_join_tab())
      {
	DBUG_VOID_RETURN;
      }
unknown's avatar
unknown committed
1594 1595 1596 1597 1598 1599 1600 1601 1602
      /*
	Here we sort rows for ORDER BY/GROUP BY clause, if the optimiser
	chose FILESORT to be faster than INDEX SCAN or there is no 
	suitable index present.
	Note, that create_sort_index calls test_if_skip_sort_order and may
	finally replace sorting with index scan if there is a LIMIT clause in
	the query. XXX: it's never shown in EXPLAIN!
	OPTION_FOUND_ROWS supersedes LIMIT and is taken into account.
      */
1603
      if (create_sort_index(thd, curr_join,
1604 1605
			    curr_join->group_list ? 
			    curr_join->group_list : curr_join->order,
unknown's avatar
unknown committed
1606 1607 1608
			    curr_join->select_limit,
			    (select_options & OPTION_FOUND_ROWS ?
			     HA_POS_ERROR : unit->select_limit_cnt)))
1609
	DBUG_VOID_RETURN;
unknown's avatar
unknown committed
1610
    }
unknown's avatar
unknown committed
1611
  }
1612 1613 1614 1615 1616 1617
  /* XXX: When can we have here thd->net.report_error not zero? */
  if (thd->net.report_error)
  {
    error= thd->net.report_error;
    DBUG_VOID_RETURN;
  }
1618
  curr_join->having= curr_join->tmp_having;
1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645
  curr_join->fields= curr_fields_list;
  curr_join->procedure= procedure;

  if (unit == &thd->lex->unit &&
      (unit->fake_select_lex == 0 || select_lex == unit->fake_select_lex) &&
      thd->cursor && tables != const_tables)
  {
    /*
      We are here if this is JOIN::exec for the last select of the main unit
      and the client requested to open a cursor.
      We check that not all tables are constant because this case is not
      handled by do_select() separately, and this case is not implemented
      for cursors yet.
    */
    DBUG_ASSERT(error == 0);
    /*
      curr_join is used only for reusable joins - that is, 
      to perform SELECT for each outer row (like in subselects).
      This join is main, so we know for sure that curr_join == join.
    */
    DBUG_ASSERT(curr_join == this);
    /* Open cursor for the last join sweep */
    error= thd->cursor->open(this);
  }
  else
  {
    thd->proc_info="Sending data";
unknown's avatar
unknown committed
1646
    DBUG_PRINT("info", ("%s", thd->proc_info));
1647 1648
    result->send_fields(*curr_fields_list,
                        Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF);
1649 1650 1651 1652 1653
    error= do_select(curr_join, curr_fields_list, NULL, procedure);
    thd->limit_found_rows= curr_join->send_records;
    thd->examined_row_count= curr_join->examined_rows;
  }

1654 1655
  DBUG_VOID_RETURN;
}
unknown's avatar
unknown committed
1656

1657

1658 1659 1660 1661 1662
/*
  Clean up join. Return error that hold JOIN.
*/

int
1663
JOIN::cleanup()
1664
{
1665
  DBUG_ENTER("JOIN::cleanup");
1666 1667 1668
  select_lex->join= 0;

  if (tmp_join)
unknown's avatar
unknown committed
1669 1670 1671 1672 1673 1674
  {
    if (join_tab != tmp_join->join_tab)
    {
      JOIN_TAB *tab, *end;
      for (tab= join_tab, end= tab+tables ; tab != end ; tab++)
      {
unknown's avatar
af  
unknown committed
1675
	tab->cleanup();
unknown's avatar
unknown committed
1676 1677 1678
      }
    }
    tmp_join->tmp_join= 0;
unknown's avatar
unknown committed
1679
    tmp_table_param.copy_field=0;
1680
    DBUG_RETURN(tmp_join->cleanup());
unknown's avatar
unknown committed
1681
  }
unknown's avatar
unknown committed
1682
  cond_equal= 0;
1683

1684
  lock=0;                                     // It's faster to unlock later
1685
  join_free(1);
unknown's avatar
af  
unknown committed
1686 1687 1688 1689
  if (exec_tmp_table1)
    free_tmp_table(thd, exec_tmp_table1);
  if (exec_tmp_table2)
    free_tmp_table(thd, exec_tmp_table2);
unknown's avatar
unknown committed
1690 1691 1692
  delete select;
  delete_dynamic(&keyuse);
  delete procedure;
1693 1694 1695
  for (SELECT_LEX_UNIT *lex_unit= select_lex->first_inner_unit();
       lex_unit != 0;
       lex_unit= lex_unit->next_unit())
1696
  {
1697
    error|= lex_unit->cleanup();
1698 1699
  }
  DBUG_RETURN(error);
1700 1701
}

1702

1703 1704 1705 1706 1707 1708 1709 1710
/************************* Cursor ******************************************/
  
void
Cursor::init_from_thd(THD *thd)
{
  /*
    We need to save and reset thd->mem_root, otherwise it'll be freed
    later in mysql_parse.
unknown's avatar
unknown committed
1711

1712 1713
    We can't just change the thd->mem_root here as we want to keep the
    things that are already allocated in thd->mem_root for Cursor::fetch()
1714
  */
unknown's avatar
unknown committed
1715
  main_mem_root=  *thd->mem_root;
1716
  state= thd->current_arena->state;
unknown's avatar
unknown committed
1717 1718
  /* Allocate new memory root for thd */
  init_sql_alloc(thd->mem_root,
1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731
                 thd->variables.query_alloc_block_size,
                 thd->variables.query_prealloc_size);

  /*
    The same is true for open tables and lock: save tables and zero THD
    pointers to prevent table close in close_thread_tables (This is a part
    of the temporary solution to make cursors work with minimal changes to
    the current source base).
  */
  derived_tables= thd->derived_tables;
  open_tables=    thd->open_tables;
  lock=           thd->lock;
  query_id=       thd->query_id;
unknown's avatar
unknown committed
1732
  free_list=	  thd->free_list;
1733 1734 1735 1736
  reset_thd(thd);
  /*
    XXX: thd->locked_tables is not changed.
    What problems can we have with it if cursor is open?
1737
    TODO: must be fixed because of the prelocked mode.
1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758
  */
}


void
Cursor::reset_thd(THD *thd)
{
  thd->derived_tables= 0;
  thd->open_tables= 0;
  thd->lock= 0;
  thd->free_list= 0;
}


int
Cursor::open(JOIN *join_arg)
{
  join= join_arg;
  THD *thd= join->thd;
  /* First non-constant table */
  JOIN_TAB *join_tab= join->join_tab + join->const_tables;
unknown's avatar
unknown committed
1759
  DBUG_ENTER("Cursor::open");
1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770

  /*
    Send fields description to the client; server_status is sent
    in 'EOF' packet, which ends send_fields().
  */
  thd->server_status|= SERVER_STATUS_CURSOR_EXISTS;
  join->result->send_fields(*join->fields, Protocol::SEND_NUM_ROWS);
  ::send_eof(thd);
  thd->server_status&= ~SERVER_STATUS_CURSOR_EXISTS;

  /* Prepare JOIN for reading rows. */
unknown's avatar
unknown committed
1771
  join->tmp_table= 0;
1772
  join->join_tab[join->tables-1].next_select= setup_end_select_func(join);
1773 1774 1775 1776
  join->send_records= 0;
  join->fetch_limit= join->unit->offset_limit_cnt;

  /* Disable JOIN CACHE as it is not working with cursors yet */
unknown's avatar
unknown committed
1777 1778 1779
  for (JOIN_TAB *tab= join_tab;
       tab != join->join_tab + join->tables - 1;
       tab++)
1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791
  {
    if (tab->next_select == sub_select_cache)
      tab->next_select= sub_select;
  }

  DBUG_ASSERT(join_tab->table->reginfo.not_exists_optimize == 0);
  DBUG_ASSERT(join_tab->not_used_in_distinct == 0);
  /*
    null_row is set only if row not found and it's outer join: should never
    happen for the first table in join_tab list
  */
  DBUG_ASSERT(join_tab->table->null_row == 0);
1792
  DBUG_RETURN(0);
1793 1794 1795 1796 1797 1798 1799 1800 1801
}


/*
  DESCRIPTION
    Fetch next num_rows rows from the cursor and sent them to the client
  PRECONDITION:
    Cursor is open
  RETURN VALUES:
1802
    none, this function will send error or OK to network if necessary.
1803 1804
*/

1805
void
1806 1807 1808
Cursor::fetch(ulong num_rows)
{
  THD *thd= join->thd;
unknown's avatar
unknown committed
1809
  JOIN_TAB *join_tab= join->join_tab + join->const_tables;
1810
  enum_nested_loop_state error= NESTED_LOOP_OK;
1811 1812
  DBUG_ENTER("Cursor::fetch");
  DBUG_PRINT("enter",("rows: %lu", num_rows));
1813

1814 1815 1816 1817 1818 1819 1820
  DBUG_ASSERT(thd->derived_tables == 0 && thd->open_tables == 0 &&
              thd->lock == 0);

  thd->derived_tables= derived_tables;
  thd->open_tables= open_tables;
  thd->lock= lock;
  thd->query_id= query_id;
1821 1822
  /* save references to memory, allocated during fetch */
  thd->set_n_backup_item_arena(this, &thd->stmt_backup);
unknown's avatar
unknown committed
1823

1824 1825
  join->fetch_limit+= num_rows;

1826 1827 1828 1829 1830 1831 1832
  error= sub_select(join, join_tab, 0);
  if (error == NESTED_LOOP_OK || error == NESTED_LOOP_NO_MORE_ROWS)
    error= sub_select(join,join_tab,1);
  if (error == NESTED_LOOP_QUERY_LIMIT)
    error= NESTED_LOOP_OK;                    /* select_limit used */
  if (error == NESTED_LOOP_CURSOR_LIMIT)
    join->resume_nested_loop= TRUE;
1833

1834
#ifdef USING_TRANSACTIONS
unknown's avatar
unknown committed
1835
    ha_release_temporary_latches(thd);
1836 1837 1838
#endif

  thd->restore_backup_item_arena(this, &thd->stmt_backup);
1839 1840 1841
  DBUG_ASSERT(thd->free_list == 0);
  reset_thd(thd);

1842
  if (error == NESTED_LOOP_CURSOR_LIMIT)
1843 1844
  {
    /* Fetch limit worked, possibly more rows are there */
1845 1846 1847
    thd->server_status|= SERVER_STATUS_CURSOR_EXISTS;
    ::send_eof(thd);
    thd->server_status&= ~SERVER_STATUS_CURSOR_EXISTS;
1848 1849 1850
  }
  else
  {
1851
    close();
1852
    if (error == NESTED_LOOP_OK)
1853 1854 1855 1856 1857
    {
      thd->server_status|= SERVER_STATUS_LAST_ROW_SENT;
      ::send_eof(thd);
      thd->server_status&= ~SERVER_STATUS_LAST_ROW_SENT;
    }
1858
    else if (error != NESTED_LOOP_KILLED)
1859
      my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0));
1860
  }
1861
  DBUG_VOID_RETURN;
1862 1863 1864 1865 1866 1867 1868
}


void
Cursor::close()
{
  THD *thd= join->thd;
unknown's avatar
unknown committed
1869 1870
  DBUG_ENTER("Cursor::close");

1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882
  join->join_free(0);
  if (unit)
  {
    /* In case of UNIONs JOIN is freed inside unit->cleanup() */
    unit->cleanup();
  }
  else
  {
    join->cleanup();
    delete join;
  }
  {
1883
    /* XXX: Another hack: closing tables used in the cursor */
1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897
    DBUG_ASSERT(lock || open_tables || derived_tables);

    TABLE *tmp_derived_tables= thd->derived_tables;
    MYSQL_LOCK *tmp_lock= thd->lock;

    thd->open_tables= open_tables;
    thd->derived_tables= derived_tables;
    thd->lock= lock;
    close_thread_tables(thd);

    thd->open_tables= tmp_derived_tables;
    thd->derived_tables= tmp_derived_tables;
    thd->lock= tmp_lock;
  }
1898 1899
  join= 0;
  unit= 0;
1900 1901 1902 1903 1904 1905 1906
  free_items(free_list);
  free_list= 0;
  /*
    Must be last, as some memory might be allocated for free purposes,
    like in free_tmp_table() (TODO: fix this issue)
  */
  free_root(mem_root, MYF(0));
unknown's avatar
unknown committed
1907
  DBUG_VOID_RETURN;
1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918
}


Cursor::~Cursor()
{
  if (is_open())
    close();
}

/*********************************************************************/

1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962
/*
  An entry point to single-unit select (a select without UNION).

  SYNOPSIS
    mysql_select()

    thd                  thread handler
    rref_pointer_array   a reference to ref_pointer_array of
                         the top-level select_lex for this query
    tables               list of all tables used in this query.
                         The tables have been pre-opened.
    wild_num             number of wildcards used in the top level 
                         select of this query.
                         For example statement
                         SELECT *, t1.*, catalog.t2.* FROM t0, t1, t2;
                         has 3 wildcards.
    fields               list of items in SELECT list of the top-level
                         select
                         e.g. SELECT a, b, c FROM t1 will have Item_field
                         for a, b and c in this list.
    conds                top level item of an expression representing
                         WHERE clause of the top level select
    og_num               total number of ORDER BY and GROUP BY clauses
                         arguments
    order                linked list of ORDER BY agruments
    group                linked list of GROUP BY arguments
    having               top level item of HAVING expression
    proc_param           list of PROCEDUREs
    select_options       select options (BIG_RESULT, etc)
    result               an instance of result set handling class.
                         This object is responsible for send result
                         set rows to the client or inserting them
                         into a table.
    select_lex           the only SELECT_LEX of this query
    unit                 top-level UNIT of this query
                         UNIT is an artificial object created by the parser
                         for every SELECT clause.
                         e.g. SELECT * FROM t1 WHERE a1 IN (SELECT * FROM t2)
                         has 2 unions.

  RETURN VALUE
   FALSE  success
   TRUE   an error
*/
1963

unknown's avatar
unknown committed
1964
bool
1965
mysql_select(THD *thd, Item ***rref_pointer_array,
unknown's avatar
unknown committed
1966
	     TABLE_LIST *tables, uint wild_num, List<Item> &fields,
1967 1968 1969
	     COND *conds, uint og_num,  ORDER *order, ORDER *group,
	     Item *having, ORDER *proc_param, ulong select_options,
	     select_result *result, SELECT_LEX_UNIT *unit,
1970
	     SELECT_LEX *select_lex)
1971
{
unknown's avatar
unknown committed
1972
  bool err;
unknown's avatar
unknown committed
1973
  bool free_join= 1;
1974 1975
  DBUG_ENTER("mysql_select");

unknown's avatar
unknown committed
1976
  JOIN *join;
1977
  if (select_lex->join != 0)
1978
  {
unknown's avatar
unknown committed
1979
    join= select_lex->join;
unknown's avatar
unknown committed
1980 1981 1982 1983
    /*
      is it single SELECT in derived table, called in derived table
      creation
    */
1984 1985
    if (select_lex->linkage != DERIVED_TABLE_TYPE ||
	(select_options & SELECT_DESCRIBE))
unknown's avatar
unknown committed
1986
    {
1987
      if (select_lex->linkage != GLOBAL_OPTIONS_TYPE)
1988
      {
1989
	//here is EXPLAIN of subselect or derived table
unknown's avatar
af  
unknown committed
1990
	if (join->change_result(result))
1991
	{
unknown's avatar
unknown committed
1992
	  DBUG_RETURN(TRUE);
1993
	}
1994
      }
1995
      else
1996
      {
1997 1998 1999 2000 2001 2002
	if (join->prepare(rref_pointer_array, tables, wild_num,
			  conds, og_num, order, group, having, proc_param,
			  select_lex, unit))
	{
	  goto err;
	}
2003
      }
unknown's avatar
unknown committed
2004
    }
unknown's avatar
af  
unknown committed
2005
    free_join= 0;
unknown's avatar
unknown committed
2006
    join->select_options= select_options;
2007
  }
unknown's avatar
unknown committed
2008 2009
  else
  {
unknown's avatar
af  
unknown committed
2010
    if (!(join= new JOIN(thd, fields, select_options, result)))
unknown's avatar
unknown committed
2011
	DBUG_RETURN(TRUE);
unknown's avatar
unknown committed
2012 2013
    thd->proc_info="init";
    thd->used_tables=0;                         // Updated by setup_fields
2014 2015
    if (join->prepare(rref_pointer_array, tables, wild_num,
		      conds, og_num, order, group, having, proc_param,
2016
		      select_lex, unit))
unknown's avatar
unknown committed
2017
    {
2018
      goto err;
unknown's avatar
unknown committed
2019 2020 2021
    }
  }

unknown's avatar
unknown committed
2022
  if ((err= join->optimize()))
unknown's avatar
unknown committed
2023
  {
unknown's avatar
unknown committed
2024 2025
    goto err;					// 1
  }
2026

unknown's avatar
unknown committed
2027
  if (thd->lex->describe & DESCRIBE_EXTENDED)
unknown's avatar
unknown committed
2028 2029 2030 2031 2032
  {
    join->conds_history= join->conds;
    join->having_history= (join->having?join->having:join->tmp_having);
  }

2033
  if (thd->net.report_error)
2034 2035 2036 2037
    goto err;

  join->exec();

2038 2039 2040 2041 2042 2043 2044 2045 2046 2047
  if (thd->cursor && thd->cursor->is_open())
  {
    /*
      A cursor was opened for the last sweep in exec().
      We are here only if this is mysql_select for top-level SELECT_LEX_UNIT
      and there were no error.
    */
    free_join= 0;
  }

unknown's avatar
unknown committed
2048
  if (thd->lex->describe & DESCRIBE_EXTENDED)
unknown's avatar
unknown committed
2049 2050 2051 2052 2053
  {
    select_lex->where= join->conds_history;
    select_lex->having= join->having_history;
  }

2054
err:
unknown's avatar
unknown committed
2055 2056 2057
  if (free_join)
  {
    thd->proc_info="end";
2058
    err= join->cleanup();
unknown's avatar
unknown committed
2059
    delete join;
unknown's avatar
unknown committed
2060
    DBUG_RETURN(err || thd->net.report_error);
unknown's avatar
unknown committed
2061
  }
unknown's avatar
unknown committed
2062
  DBUG_RETURN(join->error);
unknown's avatar
unknown committed
2063 2064 2065
}

/*****************************************************************************
2066 2067
  Create JOIN_TABS, make a guess about the table types,
  Approximate how many records will be used in each table
unknown's avatar
unknown committed
2068 2069
*****************************************************************************/

2070 2071
static ha_rows get_quick_record_count(THD *thd, SQL_SELECT *select,
				      TABLE *table,
unknown's avatar
unknown committed
2072
				      const key_map *keys,ha_rows limit)
unknown's avatar
unknown committed
2073 2074 2075 2076 2077 2078 2079
{
  int error;
  DBUG_ENTER("get_quick_record_count");
  if (select)
  {
    select->head=table;
    table->reginfo.impossible_range=0;
2080 2081
    if ((error= select->test_quick_select(thd, *(key_map *)keys,(table_map) 0,
                                          limit, 0)) == 1)
unknown's avatar
unknown committed
2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093
      DBUG_RETURN(select->quick->records);
    if (error == -1)
    {
      table->reginfo.impossible_range=1;
      DBUG_RETURN(0);
    }
    DBUG_PRINT("warning",("Couldn't use record count on const keypart"));
  }
  DBUG_RETURN(HA_POS_ERROR);			/* This shouldn't happend */
}


2094 2095 2096 2097 2098 2099 2100
/*
  Calculate the best possible join and initialize the join structure

  RETURN VALUES
  0	ok
  1	Fatal error
*/
unknown's avatar
unknown committed
2101

unknown's avatar
unknown committed
2102
static bool
2103
make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
2104
		     DYNAMIC_ARRAY *keyuse_array)
unknown's avatar
unknown committed
2105 2106
{
  int error;
2107
  TABLE *table;
2108 2109 2110
  uint i,table_count,const_count,key;
  table_map found_const_table_map, all_table_map, found_ref, refs;
  key_map const_ref, eq_part;
unknown's avatar
unknown committed
2111 2112 2113 2114 2115 2116 2117 2118
  TABLE **table_vector;
  JOIN_TAB *stat,*stat_end,*s,**stat_ref;
  KEYUSE *keyuse,*start_keyuse;
  table_map outer_join=0;
  JOIN_TAB *stat_vector[MAX_TABLES+1];
  DBUG_ENTER("make_join_statistics");

  table_count=join->tables;
2119 2120
  stat=(JOIN_TAB*) join->thd->calloc(sizeof(JOIN_TAB)*table_count);
  stat_ref=(JOIN_TAB**) join->thd->alloc(sizeof(JOIN_TAB*)*MAX_TABLES);
2121
  table_vector=(TABLE**) join->thd->alloc(sizeof(TABLE*)*(table_count*2));
unknown's avatar
unknown committed
2122 2123 2124 2125 2126 2127
  if (!stat || !stat_ref || !table_vector)
    DBUG_RETURN(1);				// Eom /* purecov: inspected */

  join->best_ref=stat_vector;

  stat_end=stat+table_count;
2128
  found_const_table_map= all_table_map=0;
unknown's avatar
unknown committed
2129 2130
  const_count=0;

unknown's avatar
VIEW  
unknown committed
2131 2132
  for (s= stat, i= 0;
       tables;
2133
       s++, tables= tables->next_leaf, i++)
unknown's avatar
unknown committed
2134
  {
2135
    TABLE_LIST *embedding= tables->embedding;
unknown's avatar
unknown committed
2136
    stat_vector[i]=s;
2137 2138 2139 2140
    s->keys.init();
    s->const_keys.init();
    s->checked_keys.init();
    s->needed_reg.init();
unknown's avatar
unknown committed
2141
    table_vector[i]=s->table=table=tables->table;
2142
    table->pos_in_table_list= tables;
unknown's avatar
unknown committed
2143
    table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);// record count
2144
    table->quick_keys.clear_all();
unknown's avatar
unknown committed
2145 2146
    table->reginfo.join_tab=s;
    table->reginfo.not_exists_optimize=0;
2147
    bzero((char*) table->const_key_parts, sizeof(key_part_map)*table->s->keys);
unknown's avatar
unknown committed
2148
    all_table_map|= table->map;
2149
    s->join=join;
2150
    s->info=0;					// For describe
2151 2152 2153

    s->dependent= tables->dep_tables;
    s->key_dependent= 0;
2154 2155
    if (tables->schema_table)
      table->file->records= 2;
2156

unknown's avatar
unknown committed
2157 2158
    s->on_expr_ref= &tables->on_expr;
    if (*s->on_expr_ref)
unknown's avatar
unknown committed
2159
    {
2160
      /* s is the only inner table of an outer join */
unknown's avatar
unknown committed
2161 2162
      if (!table->file->records)
      {						// Empty table
2163
        s->dependent= 0;                        // Ignore LEFT JOIN depend.
unknown's avatar
unknown committed
2164 2165 2166
	set_position(join,const_count++,s,(KEYUSE*) 0);
	continue;
      }
2167
      outer_join|= table->map;
unknown's avatar
unknown committed
2168 2169
      continue;
    }
2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183
    if (embedding)
    {
      /* s belongs to a nested join, maybe to several embedded joins */
      do
      {
        NESTED_JOIN *nested_join= embedding->nested_join;
        s->dependent|= embedding->dep_tables;
        embedding= embedding->embedding;
        outer_join|= nested_join->used_tables;
      }
      while (embedding);
      continue;
    }

2184
    if ((table->s->system || table->file->records <= 1) && ! s->dependent &&
2185
	!(table->file->table_flags() & HA_NOT_EXACT_COUNT) &&
unknown's avatar
unknown committed
2186
        !table->fulltext_searched)
unknown's avatar
unknown committed
2187 2188 2189 2190 2191
    {
      set_position(join,const_count++,s,(KEYUSE*) 0);
    }
  }
  stat_vector[i]=0;
2192
  join->outer_join=outer_join;
unknown's avatar
unknown committed
2193

2194
  if (join->outer_join)
unknown's avatar
unknown committed
2195
  {
2196 2197 2198 2199 2200 2201
    /* 
       Build transitive closure for relation 'to be dependent on'.
       This will speed up the plan search for many cases with outer joins,
       as well as allow us to catch illegal cross references/
       Warshall's algorithm is used to build the transitive closure.
       As we use bitmaps to represent the relation the complexity
unknown's avatar
unknown committed
2202
       of the algorithm is O((number of tables)^2). 
2203 2204
    */
    for (i= 0, s= stat ; i < table_count ; i++, s++)
unknown's avatar
unknown committed
2205
    {
2206
      for (uint j= 0 ; j < table_count ; j++)
unknown's avatar
unknown committed
2207
      {
2208 2209 2210 2211
        table= stat[j].table;
        if (s->dependent & table->map)
          s->dependent |= table->reginfo.join_tab->dependent;
      }
unknown's avatar
unknown committed
2212 2213
      if (s->dependent)
        s->table->maybe_null= 1;
2214 2215 2216 2217 2218 2219 2220
    }
    /* Catch illegal cross references for outer joins */
    for (i= 0, s= stat ; i < table_count ; i++, s++)
    {
      if (s->dependent & s->table->map)
      {
        join->tables=0;			// Don't use join->table
unknown's avatar
unknown committed
2221
        my_message(ER_WRONG_OUTER_JOIN, ER(ER_WRONG_OUTER_JOIN), MYF(0));
2222
        DBUG_RETURN(1);
unknown's avatar
unknown committed
2223
      }
2224
      s->key_dependent= s->dependent;
unknown's avatar
unknown committed
2225 2226 2227 2228
    }
  }

  if (conds || outer_join)
2229
    if (update_ref_and_keys(join->thd, keyuse_array, stat, join->tables,
unknown's avatar
unknown committed
2230 2231
                            conds, join->cond_equal,
                            ~outer_join, join->select_lex))
unknown's avatar
unknown committed
2232 2233
      DBUG_RETURN(1);

2234
  /* Read tables with 0 or 1 rows (system tables) */
2235
  join->const_table_map= 0;
2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253

  for (POSITION *p_pos=join->positions, *p_end=p_pos+const_count;
       p_pos < p_end ;
       p_pos++)
  {
    int tmp;
    s= p_pos->table;
    s->type=JT_SYSTEM;
    join->const_table_map|=s->table->map;
    if ((tmp=join_read_const_table(s, p_pos)))
    {
      if (tmp > 0)
	DBUG_RETURN(1);			// Fatal error
    }
    else
      found_const_table_map|= s->table->map;
  }

unknown's avatar
unknown committed
2254
  /* loop until no more const tables are found */
2255
  int ref_changed;
unknown's avatar
unknown committed
2256 2257
  do
  {
2258
    ref_changed = 0;
unknown's avatar
unknown committed
2259
    found_ref=0;
2260 2261 2262 2263 2264 2265 2266

    /*
      We only have to loop from stat_vector + const_count as
      set_position() will move all const_tables first in stat_vector
    */

    for (JOIN_TAB **pos=stat_vector+const_count ; (s= *pos) ; pos++)
unknown's avatar
unknown committed
2267
    {
2268
      table=s->table;
unknown's avatar
unknown committed
2269 2270
      if (s->dependent)				// If dependent on some table
      {
2271
	// All dep. must be constants
2272
	if (s->dependent & ~(found_const_table_map))
unknown's avatar
unknown committed
2273
	  continue;
2274
	if (table->file->records <= 1L &&
2275 2276
	    !(table->file->table_flags() & HA_NOT_EXACT_COUNT) &&
            !table->pos_in_table_list->embedding)
unknown's avatar
unknown committed
2277
	{					// system table
2278
	  int tmp= 0;
unknown's avatar
unknown committed
2279
	  s->type=JT_SYSTEM;
2280
	  join->const_table_map|=table->map;
unknown's avatar
unknown committed
2281
	  set_position(join,const_count++,s,(KEYUSE*) 0);
2282
	  if ((tmp= join_read_const_table(s,join->positions+const_count-1)))
2283 2284 2285 2286 2287 2288
	  {
	    if (tmp > 0)
	      DBUG_RETURN(1);			// Fatal error
	  }
	  else
	    found_const_table_map|= table->map;
unknown's avatar
unknown committed
2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299
	  continue;
	}
      }
      /* check if table can be read by key or table only uses const refs */
      if ((keyuse=s->keyuse))
      {
	s->type= JT_REF;
	while (keyuse->table == table)
	{
	  start_keyuse=keyuse;
	  key=keyuse->key;
2300
	  s->keys.set_bit(key);               // QQ: remove this ?
unknown's avatar
unknown committed
2301

2302 2303 2304
	  refs=0;
          const_ref.clear_all();
	  eq_part.clear_all();
unknown's avatar
unknown committed
2305 2306
	  do
	  {
2307
	    if (keyuse->val->type() != Item::NULL_ITEM && !keyuse->optimize)
unknown's avatar
unknown committed
2308
	    {
2309
	      if (!((~found_const_table_map) & keyuse->used_tables))
2310
		const_ref.set_bit(keyuse->keypart);
unknown's avatar
unknown committed
2311 2312
	      else
		refs|=keyuse->used_tables;
2313
	      eq_part.set_bit(keyuse->keypart);
unknown's avatar
unknown committed
2314 2315 2316 2317
	    }
	    keyuse++;
	  } while (keyuse->table == table && keyuse->key == key);

2318
	  if (eq_part.is_prefix(table->key_info[key].key_parts) &&
2319 2320
	      ((table->key_info[key].flags & (HA_NOSAME | HA_END_SPACE_KEY)) ==
	       HA_NOSAME) &&
unknown's avatar
unknown committed
2321
              !table->fulltext_searched)
unknown's avatar
unknown committed
2322 2323 2324
	  {
	    if (const_ref == eq_part)
	    {					// Found everything for ref.
2325 2326
	      int tmp;
	      ref_changed = 1;
2327
	      s->type= JT_CONST;
2328
	      join->const_table_map|=table->map;
unknown's avatar
unknown committed
2329
	      set_position(join,const_count++,s,start_keyuse);
2330
	      if (create_ref_for_key(join, s, start_keyuse,
2331
				     found_const_table_map))
2332 2333 2334 2335 2336 2337 2338 2339 2340
		DBUG_RETURN(1);
	      if ((tmp=join_read_const_table(s,
					     join->positions+const_count-1)))
	      {
		if (tmp > 0)
		  DBUG_RETURN(1);			// Fatal error
	      }
	      else
		found_const_table_map|= table->map;
unknown's avatar
unknown committed
2341 2342 2343 2344 2345 2346 2347 2348
	      break;
	    }
	    else
	      found_ref|= refs;		// Table is const if all refs are const
	  }
	}
      }
    }
2349
  } while (join->const_table_map & found_ref && ref_changed);
unknown's avatar
unknown committed
2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362

  /* Calc how many (possible) matched records in each table */

  for (s=stat ; s < stat_end ; s++)
  {
    if (s->type == JT_SYSTEM || s->type == JT_CONST)
    {
      /* Only one matching row */
      s->found_records=s->records=s->read_time=1; s->worst_seeks=1.0;
      continue;
    }
    /* Approximate found rows and time to read them */
    s->found_records=s->records=s->table->file->records;
2363
    s->read_time=(ha_rows) s->table->file->scan_time();
unknown's avatar
unknown committed
2364

2365 2366
    /*
      Set a max range of how many seeks we can expect when using keys
2367 2368
      This is can't be to high as otherwise we are likely to use
      table scan.
2369
    */
2370 2371
    s->worst_seeks= min((double) s->found_records / 10,
			(double) s->read_time*3);
unknown's avatar
unknown committed
2372 2373 2374
    if (s->worst_seeks < 2.0)			// Fix for small tables
      s->worst_seeks=2.0;

2375 2376 2377 2378 2379 2380
    /*
      Add to stat->const_keys those indexes for which all group fields or
      all select distinct fields participate in one index.
    */
    add_group_and_distinct_keys(join, s);

2381 2382
    if (!s->const_keys.is_clear_all() &&
        !s->table->pos_in_table_list->embedding)
unknown's avatar
unknown committed
2383 2384
    {
      ha_rows records;
2385 2386 2387
      SQL_SELECT *select;
      select= make_select(s->table, found_const_table_map,
			  found_const_table_map,
unknown's avatar
unknown committed
2388
			  *s->on_expr_ref ? *s->on_expr_ref : conds,
unknown's avatar
unknown committed
2389
			  1, &error);
2390 2391
      if (!select)
        DBUG_RETURN(1);
2392
      records= get_quick_record_count(join->thd, select, s->table,
unknown's avatar
unknown committed
2393
				      &s->const_keys, join->row_limit);
unknown's avatar
unknown committed
2394 2395 2396
      s->quick=select->quick;
      s->needed_reg=select->needed_reg;
      select->quick=0;
2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407
      if (records == 0 && s->table->reginfo.impossible_range)
      {
	/*
	  Impossible WHERE or ON expression
	  In case of ON, we mark that the we match one empty NULL row.
	  In case of WHERE, don't set found_const_table_map to get the
	  caller to abort with a zero row result.
	*/
	join->const_table_map|= s->table->map;
	set_position(join,const_count++,s,(KEYUSE*) 0);
	s->type= JT_CONST;
unknown's avatar
unknown committed
2408
	if (*s->on_expr_ref)
2409 2410 2411 2412 2413 2414 2415 2416
	{
	  /* Generate empty row */
	  s->info= "Impossible ON condition";
	  found_const_table_map|= s->table->map;
	  s->type= JT_CONST;
	  mark_as_null_row(s->table);		// All fields are NULL
	}
      }
unknown's avatar
unknown committed
2417 2418
      if (records != HA_POS_ERROR)
      {
2419
	s->found_records=records;
unknown's avatar
unknown committed
2420 2421
	s->read_time= (ha_rows) (s->quick ? s->quick->read_time : 0.0);
      }
2422
      delete select;
unknown's avatar
unknown committed
2423 2424 2425 2426 2427 2428 2429
    }
  }

  join->join_tab=stat;
  join->map2table=stat_ref;
  join->table= join->all_tables=table_vector;
  join->const_tables=const_count;
2430
  join->found_const_table_map=found_const_table_map;
unknown's avatar
unknown committed
2431

2432
  /* Find an optimal join order of the non-constant tables. */
unknown's avatar
unknown committed
2433
  if (join->const_tables != join->tables)
2434 2435
  {
    optimize_keyuse(join, keyuse_array);
unknown's avatar
af  
unknown committed
2436
    choose_plan(join, all_table_map & ~join->const_table_map);
2437
  }
unknown's avatar
unknown committed
2438 2439 2440 2441 2442 2443
  else
  {
    memcpy((gptr) join->best_positions,(gptr) join->positions,
	   sizeof(POSITION)*join->const_tables);
    join->best_read=1.0;
  }
2444
  /* Generate an execution plan from the found optimal join order. */
unknown's avatar
unknown committed
2445
  DBUG_RETURN(join->thd->killed || get_best_combination(join));
unknown's avatar
unknown committed
2446 2447 2448 2449
}


/*****************************************************************************
2450 2451 2452 2453 2454
  Check with keys are used and with tables references with tables
  Updates in stat:
	  keys	     Bitmap of all used keys
	  const_keys Bitmap of all keys with may be used with quick_select
	  keyuse     Pointer to possible keys
unknown's avatar
unknown committed
2455 2456 2457 2458 2459
*****************************************************************************/

typedef struct key_field_t {		// Used when finding key fields
  Field		*field;
  Item		*val;			// May be empty if diff constant
2460 2461
  uint		level;
  uint		optimize;
unknown's avatar
unknown committed
2462
  bool		eq_func;
2463 2464 2465 2466 2467
  /*
    If true, the condition this struct represents will not be satisfied
    when val IS NULL.
  */
  bool          null_rejecting; 
unknown's avatar
unknown committed
2468 2469
} KEY_FIELD;

2470 2471 2472 2473 2474 2475 2476 2477
/* Values in optimize */
#define KEY_OPTIMIZE_EXISTS		1
#define KEY_OPTIMIZE_REF_OR_NULL	2

/*
  Merge new key definitions to old ones, remove those not used in both

  This is called for OR between different levels
unknown's avatar
unknown committed
2478

2479 2480 2481 2482 2483
  To be able to do 'ref_or_null' we merge a comparison of a column
  and 'column IS NULL' to one test.  This is useful for sub select queries
  that are internally transformed to something like:

  SELECT * FROM t1 WHERE t1.key=outer_ref_field or t1.key IS NULL 
2484 2485 2486 2487 2488 2489

  KEY_FIELD::null_rejecting is processed as follows:
  result has null_rejecting=true if it is set for both ORed references.
  for example:
    (t2.key = t1.field OR t2.key  =  t1.field) -> null_rejecting=true
    (t2.key = t1.field OR t2.key <=> t1.field) -> null_rejecting=false
2490
*/
unknown's avatar
unknown committed
2491 2492 2493 2494 2495 2496 2497 2498

static KEY_FIELD *
merge_key_fields(KEY_FIELD *start,KEY_FIELD *new_fields,KEY_FIELD *end,
		 uint and_level)
{
  if (start == new_fields)
    return start;				// Impossible or
  if (new_fields == end)
unknown's avatar
unknown committed
2499
    return start;				// No new fields, skip all
unknown's avatar
unknown committed
2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511

  KEY_FIELD *first_free=new_fields;

  /* Mark all found fields in old array */
  for (; new_fields != end ; new_fields++)
  {
    for (KEY_FIELD *old=start ; old != first_free ; old++)
    {
      if (old->field == new_fields->field)
      {
	if (new_fields->val->used_tables())
	{
2512 2513 2514 2515
	  /*
	    If the value matches, we can use the key reference.
	    If not, we keep it until we have examined all new values
	  */
2516
	  if (old->val->eq(new_fields->val, old->field->binary()))
unknown's avatar
unknown committed
2517
	  {
2518 2519 2520 2521 2522
	    old->level= and_level;
	    old->optimize= ((old->optimize & new_fields->optimize &
			     KEY_OPTIMIZE_EXISTS) |
			    ((old->optimize | new_fields->optimize) &
			     KEY_OPTIMIZE_REF_OR_NULL));
unknown's avatar
unknown committed
2523 2524
            old->null_rejecting= (old->null_rejecting &&
                                  new_fields->null_rejecting);
unknown's avatar
unknown committed
2525 2526
	  }
	}
2527 2528
	else if (old->eq_func && new_fields->eq_func &&
		 old->val->eq(new_fields->val, old->field->binary()))
2529

2530 2531 2532 2533 2534 2535
	{
	  old->level= and_level;
	  old->optimize= ((old->optimize & new_fields->optimize &
			   KEY_OPTIMIZE_EXISTS) |
			  ((old->optimize | new_fields->optimize) &
			   KEY_OPTIMIZE_REF_OR_NULL));
unknown's avatar
unknown committed
2536 2537
          old->null_rejecting= (old->null_rejecting &&
                                new_fields->null_rejecting);
2538 2539 2540
	}
	else if (old->eq_func && new_fields->eq_func &&
		 (old->val->is_null() || new_fields->val->is_null()))
unknown's avatar
unknown committed
2541
	{
2542 2543 2544 2545 2546 2547
	  /* field = expression OR field IS NULL */
	  old->level= and_level;
	  old->optimize= KEY_OPTIMIZE_REF_OR_NULL;
	  /* Remember the NOT NULL value */
	  if (old->val->is_null())
	    old->val= new_fields->val;
2548
          /* The referred expression can be NULL: */ 
unknown's avatar
unknown committed
2549
          old->null_rejecting= 0;
unknown's avatar
unknown committed
2550
	}
2551
	else
unknown's avatar
unknown committed
2552
	{
2553 2554 2555 2556 2557
	  /*
	    We are comparing two different const.  In this case we can't
	    use a key-lookup on this so it's better to remove the value
	    and let the range optimzier handle it
	  */
unknown's avatar
unknown committed
2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568
	  if (old == --first_free)		// If last item
	    break;
	  *old= *first_free;			// Remove old value
	  old--;				// Retry this value
	}
      }
    }
  }
  /* Remove all not used items */
  for (KEY_FIELD *old=start ; old != first_free ;)
  {
2569
    if (old->level != and_level)
unknown's avatar
unknown committed
2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581
    {						// Not used in all levels
      if (old == --first_free)
	break;
      *old= *first_free;			// Remove old value
      continue;
    }
    old++;
  }
  return first_free;
}


2582 2583 2584 2585 2586 2587 2588
/*
  Add a possible key to array of possible keys if it's usable as a key

  SYNPOSIS
    add_key_field()
    key_fields			Pointer to add key, if usable
    and_level			And level, to be stored in KEY_FIELD
2589
    cond                        Condition predicate
2590 2591 2592
    field			Field used in comparision
    eq_func			True if we used =, <=> or IS NULL
    value			Value used for comparison with field
2593
                                Is NULL for BETWEEN and IN
2594 2595 2596 2597 2598 2599 2600 2601 2602 2603
    usable_tables		Tables which can be used for key optimization

  NOTES
    If we are doing a NOT NULL comparison on a NOT NULL field in a outer join
    table, we store this to be able to do not exists optimization later.

  RETURN
    *key_fields is incremented if we stored a key in the array
*/

unknown's avatar
unknown committed
2604
static void
2605
add_key_field(KEY_FIELD **key_fields,uint and_level, Item_func *cond,
2606
	      Field *field, bool eq_func, Item **value, uint num_values,
unknown's avatar
unknown committed
2607 2608
	      table_map usable_tables)
{
2609
  uint exists_optimize= 0;
unknown's avatar
unknown committed
2610 2611 2612
  if (!(field->flags & PART_KEY_FLAG))
  {
    // Don't remove column IS NULL on a LEFT JOIN table
2613 2614
    if (!eq_func || (*value)->type() != Item::NULL_ITEM ||
        !field->table->maybe_null || field->null_ptr)
unknown's avatar
unknown committed
2615
      return;					// Not a key. Skip it
2616
    exists_optimize= KEY_OPTIMIZE_EXISTS;
unknown's avatar
unknown committed
2617 2618 2619 2620
  }
  else
  {
    table_map used_tables=0;
2621 2622 2623
    bool optimizable=0;
    for (uint i=0; i<num_values; i++)
    {
unknown's avatar
af  
unknown committed
2624 2625
      used_tables|=(value[i])->used_tables();
      if (!((value[i])->used_tables() & (field->table->map | RAND_TABLE_BIT)))
2626 2627 2628
        optimizable=1;
    }
    if (!optimizable)
unknown's avatar
unknown committed
2629 2630 2631
      return;
    if (!(usable_tables & field->table->map))
    {
2632 2633
      if (!eq_func || (*value)->type() != Item::NULL_ITEM ||
          !field->table->maybe_null || field->null_ptr)
unknown's avatar
unknown committed
2634
	return;					// Can't use left join optimize
2635
      exists_optimize= KEY_OPTIMIZE_EXISTS;
unknown's avatar
unknown committed
2636 2637 2638 2639
    }
    else
    {
      JOIN_TAB *stat=field->table->reginfo.join_tab;
unknown's avatar
unknown committed
2640
      key_map possible_keys=field->key_start;
2641 2642
      possible_keys.intersect(field->table->keys_in_use_for_query);
      stat[0].keys.merge(possible_keys);             // Add possible keys
unknown's avatar
unknown committed
2643

2644 2645 2646 2647 2648 2649 2650 2651
      /*
	Save the following cases:
	Field op constant
	Field LIKE constant where constant doesn't start with a wildcard
	Field = field2 where field2 is in a different table
	Field op formula
	Field IS NULL
	Field IS NOT NULL
2652 2653
         Field BETWEEN ...
         Field IN ...
unknown's avatar
unknown committed
2654 2655 2656
      */
      stat[0].key_dependent|=used_tables;

2657 2658
      bool is_const=1;
      for (uint i=0; i<num_values; i++)
2659
        is_const&= value[i]->const_item();
2660
      if (is_const)
2661
        stat[0].const_keys.merge(possible_keys);
2662 2663
      /*
	We can't always use indexes when comparing a string index to a
unknown's avatar
unknown committed
2664 2665
	number. cmp_type() is checked to allow compare of dates to numbers.
        eq_func is NEVER true when num_values > 1
2666
       */
2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680
      if (!eq_func)
        return;
      if (field->result_type() == STRING_RESULT)
      {
        if ((*value)->result_type() != STRING_RESULT)
        {
          if (field->cmp_type() != (*value)->result_type())
            return;
        }
        else
        {
          /*
            We can't use indexes if the effective collation
            of the operation differ from the field collation.
unknown's avatar
af  
unknown committed
2681

2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692
            We also cannot use index on a text column, as the column may
            contain 'x' 'x\t' 'x ' and 'read_next_same' will stop after
            'x' when searching for WHERE col='x '
          */
          if (field->cmp_type() == STRING_RESULT &&
              (((Field_str*)field)->charset() != cond->compare_collation() ||
               ((*value)->type() != Item::NULL_ITEM &&
                (field->flags & BLOB_FLAG) && !field->binary())))
            return;
        }
      }
unknown's avatar
unknown committed
2693 2694
    }
  }
2695
  DBUG_ASSERT(num_values == 1);
unknown's avatar
unknown committed
2696 2697 2698 2699 2700
  /*
    For the moment eq_func is always true. This slot is reserved for future
    extensions where we want to remembers other things than just eq comparisons
  */
  DBUG_ASSERT(eq_func);
unknown's avatar
unknown committed
2701
  /* Store possible eq field */
2702 2703
  (*key_fields)->field=		field;
  (*key_fields)->eq_func=	eq_func;
unknown's avatar
unknown committed
2704
  (*key_fields)->val=		*value;
2705 2706
  (*key_fields)->level=		and_level;
  (*key_fields)->optimize=	exists_optimize;
2707 2708 2709 2710
  /*
    If the condition has form "tbl.keypart = othertbl.field" and 
    othertbl.field can be NULL, there will be no matches if othertbl.field 
    has NULL value.
unknown's avatar
unknown committed
2711 2712
    We use null_rejecting in add_not_null_conds() to add
    'othertbl.field IS NOT NULL' to tab->select_cond.
2713 2714 2715 2716
  */
  (*key_fields)->null_rejecting= (cond->functype() == Item_func::EQ_FUNC) &&
                                 ((*value)->type() == Item::FIELD_ITEM) &&
                                 ((Item_field*)*value)->field->maybe_null();
unknown's avatar
unknown committed
2717 2718 2719
  (*key_fields)++;
}

unknown's avatar
unknown committed
2720 2721 2722 2723
/*
  Add possible keys to array of possible keys originated from a simple predicate

  SYNPOSIS
2724
    add_key_equal_fields()
unknown's avatar
unknown committed
2725 2726
    key_fields			Pointer to add key, if usable
    and_level			And level, to be stored in KEY_FIELD
2727
    cond                        Condition predicate
unknown's avatar
unknown committed
2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741
    field			Field used in comparision
    eq_func			True if we used =, <=> or IS NULL
    value			Value used for comparison with field
				Is NULL for BETWEEN and IN    
    usable_tables		Tables which can be used for key optimization

  NOTES
    If field items f1 and f2 belong to the same multiple equality and
    a key is added for f1, the the same key is added for f2.

  RETURN
    *key_fields is incremented if we stored a key in the array
*/

2742 2743
static void
add_key_equal_fields(KEY_FIELD **key_fields, uint and_level,
unknown's avatar
unknown committed
2744
                     Item_func *cond, Item_field *field_item,
2745 2746 2747 2748
                     bool eq_func, Item **val,
                     uint num_values, table_map usable_tables)
{
  Field *field= field_item->field;
2749
  add_key_field(key_fields, and_level, cond, field,
2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763
                eq_func, val, num_values, usable_tables);
  Item_equal *item_equal= field_item->item_equal;
  if (item_equal)
  { 
    /*
      Add to the set of possible key values every substitution of
      the field for an equal field included into item_equal
    */
    Item_equal_iterator it(*item_equal);
    Item_field *item;
    while ((item= it++))
    {
      if (!field->eq(item->field))
      {
2764
        add_key_field(key_fields, and_level, cond, item->field,
2765 2766 2767 2768 2769 2770
                      eq_func, val, num_values, usable_tables);
      }
    }
  }
}

unknown's avatar
unknown committed
2771
static void
2772
add_key_fields(KEY_FIELD **key_fields,uint *and_level,
unknown's avatar
unknown committed
2773 2774 2775 2776
	       COND *cond, table_map usable_tables)
{
  if (cond->type() == Item_func::COND_ITEM)
  {
unknown's avatar
unknown committed
2777
    List_iterator_fast<Item> li(*((Item_cond*) cond)->argument_list());
unknown's avatar
unknown committed
2778 2779 2780 2781 2782 2783
    KEY_FIELD *org_key_fields= *key_fields;

    if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
    {
      Item *item;
      while ((item=li++))
2784
	add_key_fields(key_fields,and_level,item,usable_tables);
unknown's avatar
unknown committed
2785
      for (; org_key_fields != *key_fields ; org_key_fields++)
2786
	org_key_fields->level= *and_level;
unknown's avatar
unknown committed
2787 2788 2789 2790
    }
    else
    {
      (*and_level)++;
2791
      add_key_fields(key_fields,and_level,li++,usable_tables);
unknown's avatar
unknown committed
2792 2793 2794 2795 2796
      Item *item;
      while ((item=li++))
      {
	KEY_FIELD *start_key_fields= *key_fields;
	(*and_level)++;
2797
	add_key_fields(key_fields,and_level,item,usable_tables);
unknown's avatar
unknown committed
2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808
	*key_fields=merge_key_fields(org_key_fields,start_key_fields,
				     *key_fields,++(*and_level));
      }
    }
    return;
  }
  /* If item is of type 'field op field/constant' add it to key_fields */

  if (cond->type() != Item::FUNC_ITEM)
    return;
  Item_func *cond_func= (Item_func*) cond;
unknown's avatar
unknown committed
2809 2810 2811
  if (cond_func->functype() == Item_func::NOT_FUNC)
  {
    Item *item= cond_func->arguments()[0];
unknown's avatar
unknown committed
2812 2813 2814 2815
    /*
      At this moment all NOT before simple comparison predicates
      are eliminated. NOT IN and NOT BETWEEN are treated similar
      IN and BETWEEN respectively.
unknown's avatar
unknown committed
2816
    */
unknown's avatar
unknown committed
2817 2818 2819 2820 2821
    if (item->type() == Item::FUNC_ITEM &&
        ((Item_func *) item)->select_optimize() == Item_func::OPTIMIZE_KEY)
      add_key_fields(key_fields,and_level,item,usable_tables);
    return;
  }
unknown's avatar
unknown committed
2822 2823 2824 2825
  switch (cond_func->select_optimize()) {
  case Item_func::OPTIMIZE_NONE:
    break;
  case Item_func::OPTIMIZE_KEY:
unknown's avatar
unknown committed
2826 2827
  {
    // BETWEEN, IN, NE
2828
    if (cond_func->key_item()->real_item()->type() == Item::FIELD_ITEM &&
unknown's avatar
unknown committed
2829
	!(cond_func->used_tables() & OUTER_REF_TABLE_BIT))
unknown's avatar
unknown committed
2830 2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843
    {
      Item **values= cond_func->arguments()+1;
      if (cond_func->functype() == Item_func::NE_FUNC &&
        cond_func->arguments()[1]->real_item()->type() == Item::FIELD_ITEM &&
	     !(cond_func->arguments()[0]->used_tables() & OUTER_REF_TABLE_BIT))
        values--;
      add_key_equal_fields(key_fields, *and_level, cond_func,
                           (Item_field*) (cond_func->key_item()->real_item()),
                           cond_func->argument_count() == 2 &&
                           cond_func->functype() == Item_func::IN_FUNC,
                           values,
                           cond_func->argument_count()-1,
                           usable_tables);
    }
unknown's avatar
unknown committed
2844
    break;
unknown's avatar
unknown committed
2845
  }
unknown's avatar
unknown committed
2846 2847 2848 2849 2850
  case Item_func::OPTIMIZE_OP:
  {
    bool equal_func=(cond_func->functype() == Item_func::EQ_FUNC ||
		     cond_func->functype() == Item_func::EQUAL_FUNC);

2851
    if (cond_func->arguments()[0]->real_item()->type() == Item::FIELD_ITEM &&
unknown's avatar
unknown committed
2852
	!(cond_func->arguments()[0]->used_tables() & OUTER_REF_TABLE_BIT))
unknown's avatar
unknown committed
2853
    {
2854
      add_key_equal_fields(key_fields, *and_level, cond_func,
2855 2856 2857
	                (Item_field*) (cond_func->arguments()[0])->real_item(),
		           equal_func,
		           cond_func->arguments()+1, 1, usable_tables);
unknown's avatar
unknown committed
2858
    }
unknown's avatar
unknown committed
2859
    if (cond_func->arguments()[1]->real_item()->type() == Item::FIELD_ITEM &&
2860
	cond_func->functype() != Item_func::LIKE_FUNC &&
unknown's avatar
unknown committed
2861
	!(cond_func->arguments()[1]->used_tables() & OUTER_REF_TABLE_BIT))
unknown's avatar
unknown committed
2862
    {
2863
      add_key_equal_fields(key_fields, *and_level, cond_func, 
2864 2865 2866
                       (Item_field*) (cond_func->arguments()[1])->real_item(),
		           equal_func,
		           cond_func->arguments(),1,usable_tables);
unknown's avatar
unknown committed
2867 2868 2869 2870 2871
    }
    break;
  }
  case Item_func::OPTIMIZE_NULL:
    /* column_name IS [NOT] NULL */
2872
    if (cond_func->arguments()[0]->real_item()->type() == Item::FIELD_ITEM &&
unknown's avatar
unknown committed
2873
	!(cond_func->used_tables() & OUTER_REF_TABLE_BIT))
unknown's avatar
unknown committed
2874
    {
2875
      Item *tmp=new Item_null;
2876
      if (unlikely(!tmp))                       // Should never be true
unknown's avatar
unknown committed
2877
	return;
2878
      add_key_equal_fields(key_fields, *and_level, cond_func,
2879
		    (Item_field*) (cond_func->arguments()[0])->real_item(),
unknown's avatar
unknown committed
2880
		    cond_func->functype() == Item_func::ISNULL_FUNC,
2881
		    &tmp, 1, usable_tables);
unknown's avatar
unknown committed
2882 2883
    }
    break;
2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897
  case Item_func::OPTIMIZE_EQUAL:
    Item_equal *item_equal= (Item_equal *) cond;
    Item *const_item= item_equal->get_const();
    Item_equal_iterator it(*item_equal);
    Item_field *item;
    if (const_item)
    {
      /*
        For each field field1 from item_equal consider the equality 
        field1=const_item as a condition allowing an index access of the table
        with field1 by the keys value of field1.
      */   
      while ((item= it++))
      {
unknown's avatar
unknown committed
2898
        add_key_field(key_fields, *and_level, cond_func, item->field,
2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917
                      TRUE, &const_item, 1, usable_tables);
      }
    }
    else 
    {
      /*
        Consider all pairs of different fields included into item_equal.
        For each of them (field1, field1) consider the equality 
        field1=field2 as a condition allowing an index access of the table
        with field1 by the keys value of field2.
      */   
      Item_equal_iterator fi(*item_equal);
      while ((item= fi++))
      {
        Field *field= item->field;
        while ((item= it++))
        {
          if (!field->eq(item->field))
          {
unknown's avatar
unknown committed
2918
            add_key_field(key_fields, *and_level, cond_func, field,
2919 2920 2921 2922 2923 2924 2925
                          TRUE, (Item **) &item, 1, usable_tables);
          }
        }
        it.rewind();
      }
    }
    break;
unknown's avatar
unknown committed
2926 2927 2928 2929
  }
}

/*
2930 2931
  Add all keys with uses 'field' for some keypart
  If field->and_level != and_level then only mark key_part as const_part
unknown's avatar
unknown committed
2932 2933 2934
*/

static uint
2935
max_part_bit(key_part_map bits)
unknown's avatar
unknown committed
2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948
{
  uint found;
  for (found=0; bits & 1 ; found++,bits>>=1) ;
  return found;
}

static void
add_key_part(DYNAMIC_ARRAY *keyuse_array,KEY_FIELD *key_field)
{
  Field *field=key_field->field;
  TABLE *form= field->table;
  KEYUSE keyuse;

2949
  if (key_field->eq_func && !(key_field->optimize & KEY_OPTIMIZE_EXISTS))
unknown's avatar
unknown committed
2950
  {
2951
    for (uint key=0 ; key < form->s->keys ; key++)
unknown's avatar
unknown committed
2952
    {
2953
      if (!(form->keys_in_use_for_query.is_set(key)))
unknown's avatar
unknown committed
2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2966
	continue;
      if (form->key_info[key].flags & HA_FULLTEXT)
	continue;    // ToDo: ft-keys in non-ft queries.   SerG

      uint key_parts= (uint) form->key_info[key].key_parts;
      for (uint part=0 ; part <  key_parts ; part++)
      {
	if (field->eq(form->key_info[key].key_part[part].field))
	{
	  keyuse.table= field->table;
	  keyuse.val =  key_field->val;
	  keyuse.key =  key;
	  keyuse.keypart=part;
2967
	  keyuse.keypart_map= (key_part_map) 1 << part;
unknown's avatar
unknown committed
2968
	  keyuse.used_tables=key_field->val->used_tables();
2969
	  keyuse.optimize= key_field->optimize & KEY_OPTIMIZE_REF_OR_NULL;
2970
          keyuse.null_rejecting= key_field->null_rejecting;
unknown's avatar
unknown committed
2971 2972 2973 2974 2975 2976 2977
	  VOID(insert_dynamic(keyuse_array,(gptr) &keyuse));
	}
      }
    }
  }
}

unknown's avatar
unknown committed
2978 2979 2980

#define FT_KEYPART   (MAX_REF_PARTS+10)

unknown's avatar
unknown committed
2981 2982 2983 2984
static void
add_ft_keys(DYNAMIC_ARRAY *keyuse_array,
            JOIN_TAB *stat,COND *cond,table_map usable_tables)
{
2985
  Item_func_match *cond_func=NULL;
unknown's avatar
unknown committed
2986

2987 2988 2989
  if (!cond)
    return;

2990 2991
  if (cond->type() == Item::FUNC_ITEM)
  {
2992 2993 2994
    Item_func *func=(Item_func *)cond;
    Item_func::Functype functype=  func->functype();
    if (functype == Item_func::FT_FUNC)
2995
      cond_func=(Item_func_match *)cond;
2996 2997 2998 2999
    else if (func->arg_count == 2)
    {
      Item_func *arg0=(Item_func *)(func->arguments()[0]),
                *arg1=(Item_func *)(func->arguments()[1]);
3000
      if (arg1->const_item()  &&
3001 3002
          ((functype == Item_func::GE_FUNC && arg1->val_real() > 0) ||
           (functype == Item_func::GT_FUNC && arg1->val_real() >=0))  &&
3003 3004
           arg0->type() == Item::FUNC_ITEM            &&
           arg0->functype() == Item_func::FT_FUNC)
3005
        cond_func=(Item_func_match *) arg0;
3006
      else if (arg0->const_item() &&
3007 3008
               ((functype == Item_func::LE_FUNC && arg0->val_real() > 0) ||
                (functype == Item_func::LT_FUNC && arg0->val_real() >=0)) &&
3009
                arg1->type() == Item::FUNC_ITEM          &&
3010
                arg1->functype() == Item_func::FT_FUNC)
3011 3012
        cond_func=(Item_func_match *) arg1;
    }
3013 3014 3015
  }
  else if (cond->type() == Item::COND_ITEM)
  {
unknown's avatar
unknown committed
3016
    List_iterator_fast<Item> li(*((Item_cond*) cond)->argument_list());
3017 3018 3019 3020 3021

    if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
    {
      Item *item;
      while ((item=li++))
3022
        add_ft_keys(keyuse_array,stat,item,usable_tables);
3023 3024 3025
    }
  }

3026 3027
  if (!cond_func || cond_func->key == NO_SUCH_KEY ||
      !(usable_tables & cond_func->table->map))
3028
    return;
unknown's avatar
unknown committed
3029 3030 3031

  KEYUSE keyuse;
  keyuse.table= cond_func->table;
3032
  keyuse.val =  cond_func;
unknown's avatar
unknown committed
3033
  keyuse.key =  cond_func->key;
unknown's avatar
unknown committed
3034
  keyuse.keypart= FT_KEYPART;
3035
  keyuse.used_tables=cond_func->key_item()->used_tables();
unknown's avatar
unknown committed
3036
  keyuse.optimize= 0;
unknown's avatar
unknown committed
3037
  keyuse.keypart_map= 0;
unknown's avatar
unknown committed
3038 3039 3040
  VOID(insert_dynamic(keyuse_array,(gptr) &keyuse));
}

3041

unknown's avatar
unknown committed
3042 3043 3044
static int
sort_keyuse(KEYUSE *a,KEYUSE *b)
{
3045
  int res;
unknown's avatar
unknown committed
3046 3047 3048 3049 3050 3051
  if (a->table->tablenr != b->table->tablenr)
    return (int) (a->table->tablenr - b->table->tablenr);
  if (a->key != b->key)
    return (int) (a->key - b->key);
  if (a->keypart != b->keypart)
    return (int) (a->keypart - b->keypart);
3052
  // Place const values before other ones
3053 3054
  if ((res= test((a->used_tables & ~OUTER_REF_TABLE_BIT)) -
       test((b->used_tables & ~OUTER_REF_TABLE_BIT))))
3055 3056 3057 3058
    return res;
  /* Place rows that are not 'OPTIMIZE_REF_OR_NULL' first */
  return (int) ((a->optimize & KEY_OPTIMIZE_REF_OR_NULL) -
		(b->optimize & KEY_OPTIMIZE_REF_OR_NULL));
unknown's avatar
unknown committed
3059 3060 3061 3062
}


/*
3063
  Update keyuse array with all possible keys we can use to fetch rows
3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079
  
  SYNOPSIS
    update_ref_and_keys()
      thd 
      keyuse     OUT Put here ordered array of KEYUSE structures
      join_tab       Array in tablenr_order
      tables         Number of tables in join
      cond           WHERE condition (note that the function analyzes 
                     join_tab[i]->on_expr too)
      normal_tables  tables not inner w.r.t some outer join (ones for which
                     we can make ref access based the WHERE clause)
      select_lex     current SELECT
      
  RETURN 
   0 - OK
   1 - Out of memory.
unknown's avatar
unknown committed
3080 3081 3082
*/

static bool
3083
update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab,
unknown's avatar
unknown committed
3084 3085
		    uint tables, COND *cond, COND_EQUAL *cond_equal,
                    table_map normal_tables, SELECT_LEX *select_lex)
unknown's avatar
unknown committed
3086 3087
{
  uint	and_level,i,found_eq_constant;
unknown's avatar
unknown committed
3088
  KEY_FIELD *key_fields, *end, *field;
unknown's avatar
unknown committed
3089 3090 3091 3092
  uint m= 1;
  
  if (cond_equal && cond_equal->max_members)
    m= cond_equal->max_members;
unknown's avatar
unknown committed
3093

3094
  if (!(key_fields=(KEY_FIELD*)
unknown's avatar
merge  
unknown committed
3095
	thd->alloc(sizeof(key_fields[0])*
unknown's avatar
unknown committed
3096
		   (thd->lex->current_select->cond_count+1)*2*m)))
3097
    return TRUE; /* purecov: inspected */
unknown's avatar
unknown committed
3098 3099 3100 3101
  and_level= 0;
  field= end= key_fields;
  if (my_init_dynamic_array(keyuse,sizeof(KEYUSE),20,64))
    return TRUE;
3102
  if (cond)
unknown's avatar
unknown committed
3103
  {
3104
    add_key_fields(&end,&and_level,cond,normal_tables);
unknown's avatar
unknown committed
3105
    for (; field != end ; field++)
unknown's avatar
unknown committed
3106
    {
unknown's avatar
unknown committed
3107 3108 3109 3110 3111
      add_key_part(keyuse,field);
      /* Mark that we can optimize LEFT JOIN */
      if (field->val->type() == Item::NULL_ITEM &&
	  !field->field->real_maybe_null())
	field->field->table->reginfo.not_exists_optimize=1;
unknown's avatar
unknown committed
3112
    }
unknown's avatar
unknown committed
3113
  }
3114
  for (i=0 ; i < tables ; i++)
unknown's avatar
unknown committed
3115
  {
3116 3117 3118 3119 3120 3121 3122 3123 3124
    /*
      Block the creation of keys for inner tables of outer joins.
      Here only the outer joins that can not be converted to
      inner joins are left and all nests that can be eliminated
      are flattened.
      In the future when we introduce conditional accesses
      for inner tables in outer joins these keys will be taken
      into account as well.
    */ 
unknown's avatar
unknown committed
3125
    if (*join_tab[i].on_expr_ref)
unknown's avatar
unknown committed
3126
    {
3127
      add_key_fields(&end,&and_level,*join_tab[i].on_expr_ref,
3128
		     join_tab[i].table->map);
unknown's avatar
unknown committed
3129
    }
3130 3131 3132 3133 3134 3135 3136 3137
    else 
    {
      TABLE_LIST *tab= join_tab[i].table->pos_in_table_list;
      TABLE_LIST *embedding= tab->embedding;
      if (embedding)
      {
        NESTED_JOIN *nested_join= embedding->nested_join;
        if (nested_join->join_list.head() == tab)
unknown's avatar
unknown committed
3138
          add_key_fields(&end, &and_level, embedding->on_expr,
3139 3140 3141
                         nested_join->used_tables);
      }
    }
unknown's avatar
unknown committed
3142
  }
3143
  /* fill keyuse with found key parts */
unknown's avatar
unknown committed
3144
  for ( ; field != end ; field++)
3145
    add_key_part(keyuse,field);
unknown's avatar
unknown committed
3146

3147
  if (select_lex->ftfunc_list->elements)
unknown's avatar
unknown committed
3148 3149 3150 3151 3152
  {
    add_ft_keys(keyuse,join_tab,cond,normal_tables);
  }

  /*
3153
    Sort the array of possible keys and remove the following key parts:
3154
    - ref if there is a keypart which is a ref and a const.
3155 3156 3157 3158 3159 3160
      (e.g. if there is a key(a,b) and the clause is a=3 and b=7 and b=t2.d,
      then we skip the key part corresponding to b=t2.d)
    - keyparts without previous keyparts
      (e.g. if there is a key(a,b,c) but only b < 5 (or a=2 and c < 3) is
      used in the query, we drop the partial key parts from consideration).
    Special treatment for ft-keys.
unknown's avatar
unknown committed
3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177
  */
  if (keyuse->elements)
  {
    KEYUSE end,*prev,*save_pos,*use;

    qsort(keyuse->buffer,keyuse->elements,sizeof(KEYUSE),
	  (qsort_cmp) sort_keyuse);

    bzero((char*) &end,sizeof(end));		/* Add for easy testing */
    VOID(insert_dynamic(keyuse,(gptr) &end));

    use=save_pos=dynamic_element(keyuse,0,KEYUSE*);
    prev=&end;
    found_eq_constant=0;
    for (i=0 ; i < keyuse->elements-1 ; i++,use++)
    {
      if (!use->used_tables)
3178
	use->table->const_key_parts[use->key]|= use->keypart_map;
unknown's avatar
unknown committed
3179 3180
      if (use->keypart != FT_KEYPART)
      {
3181 3182 3183 3184 3185 3186 3187 3188
	if (use->key == prev->key && use->table == prev->table)
	{
	  if (prev->keypart+1 < use->keypart ||
	      prev->keypart == use->keypart && found_eq_constant)
	    continue;				/* remove */
	}
	else if (use->keypart != 0)		// First found must be 0
	  continue;
unknown's avatar
unknown committed
3189 3190 3191 3192 3193 3194 3195 3196
      }

      *save_pos= *use;
      prev=use;
      found_eq_constant= !use->used_tables;
      /* Save ptr to first use */
      if (!use->table->reginfo.join_tab->keyuse)
	use->table->reginfo.join_tab->keyuse=save_pos;
3197
      use->table->reginfo.join_tab->checked_keys.set_bit(use->key);
unknown's avatar
unknown committed
3198 3199 3200 3201 3202 3203 3204 3205 3206
      save_pos++;
    }
    i=(uint) (save_pos-(KEYUSE*) keyuse->buffer);
    VOID(set_dynamic(keyuse,(gptr) &end,i));
    keyuse->elements=i;
  }
  return FALSE;
}

3207
/*
unknown's avatar
af  
unknown committed
3208
  Update some values in keyuse for faster choose_plan() loop
3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224 3225
*/

static void optimize_keyuse(JOIN *join, DYNAMIC_ARRAY *keyuse_array)
{
  KEYUSE *end,*keyuse= dynamic_element(keyuse_array, 0, KEYUSE*);

  for (end= keyuse+ keyuse_array->elements ; keyuse < end ; keyuse++)
  {
    table_map map;
    /*
      If we find a ref, assume this table matches a proportional
      part of this table.
      For example 100 records matching a table with 5000 records
      gives 5000/100 = 50 records per key
      Constant tables are ignored.
      To avoid bad matches, we don't make ref_table_rows less than 100.
    */
unknown's avatar
unknown committed
3226
    keyuse->ref_table_rows= ~(ha_rows) 0;	// If no ref
3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238
    if (keyuse->used_tables &
	(map= (keyuse->used_tables & ~join->const_table_map &
	       ~OUTER_REF_TABLE_BIT)))
    {
      uint tablenr;
      for (tablenr=0 ; ! (map & 1) ; map>>=1, tablenr++) ;
      if (map == 1)			// Only one table
      {
	TABLE *tmp_table=join->all_tables[tablenr];
	keyuse->ref_table_rows= max(tmp_table->file->records, 100);
      }
    }
unknown's avatar
af  
unknown committed
3239 3240 3241 3242 3243 3244 3245 3246 3247 3248
    /*
      Outer reference (external field) is constant for single executing
      of subquery
    */
    if (keyuse->used_tables == OUTER_REF_TABLE_BIT)
      keyuse->ref_table_rows= 1;
  }
}


3249 3250 3251 3252 3253 3254 3255 3256 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270 3271 3272 3273 3274 3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293 3294 3295 3296 3297 3298 3299 3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310
/*
  Discover the indexes that can be used for GROUP BY or DISTINCT queries.

  SYNOPSIS
    add_group_and_distinct_keys()
    join
    join_tab

  DESCRIPTION
    If the query has a GROUP BY clause, find all indexes that contain all
    GROUP BY fields, and add those indexes to join->const_keys.
    If the query has a DISTINCT clause, find all indexes that contain all
    SELECT fields, and add those indexes to join->const_keys.
    This allows later on such queries to be processed by a
    QUICK_GROUP_MIN_MAX_SELECT.

  RETURN
    None
*/

static void
add_group_and_distinct_keys(JOIN *join, JOIN_TAB *join_tab)
{
  List<Item_field> indexed_fields;
  List_iterator<Item_field> indexed_fields_it(indexed_fields);
  ORDER      *cur_group;
  Item_field *cur_item;
  key_map possible_keys(0);

  if (join->group_list)
  { /* Collect all query fields referenced in the GROUP clause. */
    for (cur_group= join->group_list; cur_group; cur_group= cur_group->next)
      (*cur_group->item)->walk(&Item::collect_item_field_processor,
                               (byte*) &indexed_fields);
  }
  else if (join->select_distinct)
  { /* Collect all query fields referenced in the SELECT clause. */
    List<Item> &select_items= join->fields_list;
    List_iterator<Item> select_items_it(select_items);
    Item *item;
    while ((item= select_items_it++))
      item->walk(&Item::collect_item_field_processor, (byte*) &indexed_fields);
  }
  else
    return;

  if (indexed_fields.elements == 0)
    return;

  /* Intersect the keys of all group fields. */
  cur_item= indexed_fields_it++;
  possible_keys.merge(cur_item->field->part_of_key);
  while ((cur_item= indexed_fields_it++))
  {
    possible_keys.intersect(cur_item->field->part_of_key);
  }

  if (!possible_keys.is_clear_all())
    join_tab->const_keys.merge(possible_keys);
}


unknown's avatar
af  
unknown committed
3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 3321 3322 3323 3324 3325 3326 3327 3328 3329 3330 3331 3332 3333 3334 3335 3336 3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 3349 3350 3351 3352 3353 3354 3355 3356 3357 3358 3359 3360 3361 3362 3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 3373 3374 3375 3376 3377 3378 3379 3380 3381 3382 3383 3384 3385 3386 3387 3388 3389 3390 3391 3392 3393 3394 3395 3396 3397 3398 3399 3400 3401 3402 3403 3404 3405 3406 3407 3408 3409 3410 3411 3412 3413 3414 3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 3427 3428 3429 3430 3431 3432 3433 3434 3435 3436 3437 3438 3439 3440 3441 3442 3443 3444 3445 3446 3447 3448 3449 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 3471 3472 3473 3474 3475 3476 3477 3478 3479 3480 3481
/*****************************************************************************
  Go through all combinations of not marked tables and find the one
  which uses least records
*****************************************************************************/

/* Save const tables first as used tables */

static void
set_position(JOIN *join,uint idx,JOIN_TAB *table,KEYUSE *key)
{
  join->positions[idx].table= table;
  join->positions[idx].key=key;
  join->positions[idx].records_read=1.0;	/* This is a const table */

  /* Move the const table as down as possible in best_ref */
  JOIN_TAB **pos=join->best_ref+idx+1;
  JOIN_TAB *next=join->best_ref[idx];
  for (;next != table ; pos++)
  {
    JOIN_TAB *tmp=pos[0];
    pos[0]=next;
    next=tmp;
  }
  join->best_ref[idx]=table;
}


/*
  Find the best access path for an extension of a partial execution plan and
  add this path to the plan.

  SYNOPSIS
    best_access_path()
    join             pointer to the structure providing all context info
                     for the query
    s                the table to be joined by the function
    thd              thread for the connection that submitted the query
    remaining_tables set of tables not included into the partial plan yet
    idx              the length of the partial plan
    record_count     estimate for the number of records returned by the partial
                     plan
    read_time        the cost of the partial plan

  DESCRIPTION
    The function finds the best access path to table 's' from the passed
    partial plan where an access path is the general term for any means to
    access the data in 's'. An access path may use either an index or a scan,
    whichever is cheaper. The input partial plan is passed via the array
    'join->positions' of length 'idx'. The chosen access method for 's' and its
    cost are stored in 'join->positions[idx]'.

  RETURN
    None
*/

static void
best_access_path(JOIN      *join,
                 JOIN_TAB  *s,
                 THD       *thd,
                 table_map remaining_tables,
                 uint      idx,
                 double    record_count,
                 double    read_time)
{
  KEYUSE *best_key=         0;
  uint best_max_key_part=   0;
  my_bool found_constraint= 0;
  double best=              DBL_MAX;
  double best_time=         DBL_MAX;
  double records=           DBL_MAX;
  double tmp;
  ha_rows rec;

  DBUG_ENTER("best_access_path");

  if (s->keyuse)
  {                                            /* Use key if possible */
    TABLE *table= s->table;
    KEYUSE *keyuse,*start_key=0;
    double best_records= DBL_MAX;
    uint max_key_part=0;

    /* Test how we can use keys */
    rec= s->records/MATCHING_ROWS_IN_OTHER_TABLE;  // Assumed records/key
    for (keyuse=s->keyuse ; keyuse->table == table ;)
    {
      key_part_map found_part= 0;
      table_map found_ref=     0;
      uint found_ref_or_null=  0;
      uint key=     keyuse->key;
      KEY *keyinfo= table->key_info+key;
      bool ft_key=  (keyuse->keypart == FT_KEYPART);

      /* Calculate how many key segments of the current key we can use */
      start_key= keyuse;
      do
      { /* for each keypart */
        uint keypart= keyuse->keypart;
        uint found_part_ref_or_null= KEY_OPTIMIZE_REF_OR_NULL;
        do
        {
          if (!(remaining_tables & keyuse->used_tables) &&
              !(found_ref_or_null & keyuse->optimize))
          {
            found_part|= keyuse->keypart_map;
            found_ref|=  keyuse->used_tables;
            if (rec > keyuse->ref_table_rows)
              rec= keyuse->ref_table_rows;
            found_part_ref_or_null&= keyuse->optimize;
          }
          keyuse++;
          found_ref_or_null|= found_part_ref_or_null;
        } while (keyuse->table == table && keyuse->key == key &&
                 keyuse->keypart == keypart);
      } while (keyuse->table == table && keyuse->key == key);

      /*
        Assume that that each key matches a proportional part of table.
      */
      if (!found_part && !ft_key)
        continue;                               // Nothing usable found

      if (rec < MATCHING_ROWS_IN_OTHER_TABLE)
        rec= MATCHING_ROWS_IN_OTHER_TABLE;      // Fix for small tables

      /*
        ft-keys require special treatment
      */
      if (ft_key)
      {
        /*
          Really, there should be records=0.0 (yes!)
          but 1.0 would be probably safer
        */
        tmp= prev_record_reads(join, found_ref);
        records= 1.0;
      }
      else
      {
        found_constraint= 1;
        /*
          Check if we found full key
        */
        if (found_part == PREV_BITS(uint,keyinfo->key_parts) &&
            !found_ref_or_null)
        {                                         /* use eq key */
          max_key_part= (uint) ~0;
          if ((keyinfo->flags & (HA_NOSAME | HA_NULL_PART_KEY)) == HA_NOSAME)
          {
            tmp = prev_record_reads(join, found_ref);
            records=1.0;
          }
          else
          {
            if (!found_ref)
            {                                     /* We found a const key */
              if (table->quick_keys.is_set(key))
                records= (double) table->quick_rows[key];
              else
              {
                /* quick_range couldn't use key! */
                records= (double) s->records/rec;
              }
            }
            else
            {
              if (!(records=keyinfo->rec_per_key[keyinfo->key_parts-1]))
              {                                   /* Prefer longer keys */
                records=
                  ((double) s->records / (double) rec *
                   (1.0 +
3482 3483
                    ((double) (table->s->max_key_length-keyinfo->key_length) /
                     (double) table->s->max_key_length)));
unknown's avatar
af  
unknown committed
3484 3485 3486 3487 3488 3489 3490 3491 3492 3493 3494 3495 3496 3497 3498 3499 3500 3501 3502 3503 3504 3505 3506 3507 3508 3509
                if (records < 2.0)
                  records=2.0;               /* Can't be as good as a unique */
              }
            }
            /* Limit the number of matched rows */
            tmp = records;
            set_if_smaller(tmp, (double) thd->variables.max_seeks_for_key);
            if (table->used_keys.is_set(key))
            {
              /* we can use only index tree */
              uint keys_per_block= table->file->block_size/2/
                (keyinfo->key_length+table->file->ref_length)+1;
              tmp = record_count*(tmp+keys_per_block-1)/keys_per_block;
            }
            else
              tmp = record_count*min(tmp,s->worst_seeks);
          }
        }
        else
        {
          /*
            Use as much key-parts as possible and a uniq key is better
            than a not unique key
            Set tmp to (previous record count) * (records / combination)
          */
          if ((found_part & 1) &&
unknown's avatar
unknown committed
3510
              (!(table->file->index_flags(key, 0, 0) & HA_ONLY_WHOLE_INDEX) ||
unknown's avatar
af  
unknown committed
3511 3512 3513 3514 3515 3516 3517 3518 3519 3520 3521 3522 3523 3524 3525 3526 3527 3528 3529
               found_part == PREV_BITS(uint,keyinfo->key_parts)))
          {
            max_key_part=max_part_bit(found_part);
            /*
              Check if quick_range could determinate how many rows we
              will match
            */
            if (table->quick_keys.is_set(key) &&
                table->quick_key_parts[key] == max_key_part)
              tmp= records= (double) table->quick_rows[key];
            else
            {
              /* Check if we have statistic about the distribution */
              if ((records = keyinfo->rec_per_key[max_key_part-1]))
                tmp = records;
              else
              {
                /*
                  Assume that the first key part matches 1% of the file
unknown's avatar
unknown committed
3530
                  and that the whole key matches 10 (duplicates) or 1
unknown's avatar
af  
unknown committed
3531 3532 3533 3534 3535 3536 3537
                  (unique) records.
                  Assume also that more key matches proportionally more
                  records
                  This gives the formula:
                  records = (x * (b-a) + a*c-b)/(c-1)

                  b = records matched by whole key
unknown's avatar
unknown committed
3538
                  a = records matched by first key part (1% of all records?)
unknown's avatar
af  
unknown committed
3539 3540 3541 3542 3543 3544 3545 3546 3547 3548 3549 3550 3551 3552 3553
                  c = number of key parts in key
                  x = used key parts (1 <= x <= c)
                */
                double rec_per_key;
                if (!(rec_per_key=(double)
                      keyinfo->rec_per_key[keyinfo->key_parts-1]))
                  rec_per_key=(double) s->records/rec+1;

                if (!s->records)
                  tmp = 0;
                else if (rec_per_key/(double) s->records >= 0.01)
                  tmp = rec_per_key;
                else
                {
                  double a=s->records*0.01;
unknown's avatar
unknown committed
3554 3555 3556 3557 3558 3559
                  if (keyinfo->key_parts > 1)
                    tmp= (max_key_part * (rec_per_key - a) +
                          a*keyinfo->key_parts - rec_per_key)/
                         (keyinfo->key_parts-1);
                  else
                    tmp= a;
unknown's avatar
af  
unknown committed
3560 3561 3562 3563 3564 3565 3566 3567 3568 3569 3570 3571 3572 3573 3574 3575 3576 3577 3578 3579 3580 3581 3582 3583 3584 3585 3586 3587 3588 3589 3590 3591 3592 3593 3594 3595 3596 3597 3598 3599 3600 3601 3602 3603 3604 3605 3606 3607 3608 3609 3610 3611 3612 3613 3614 3615 3616 3617 3618 3619 3620 3621 3622 3623 3624 3625 3626 3627 3628 3629 3630 3631 3632 3633 3634 3635 3636 3637 3638 3639 3640 3641 3642 3643 3644 3645 3646 3647 3648 3649 3650 3651 3652
                  set_if_bigger(tmp,1.0);
                }
                records = (ulong) tmp;
              }
              /*
                If quick_select was used on a part of this key, we know
                the maximum number of rows that the key can match.
              */
              if (table->quick_keys.is_set(key) &&
                  table->quick_key_parts[key] <= max_key_part &&
                  records > (double) table->quick_rows[key])
                tmp= records= (double) table->quick_rows[key];
              else if (found_ref_or_null)
              {
                /* We need to do two key searches to find key */
                tmp *= 2.0;
                records *= 2.0;
              }
            }
            /* Limit the number of matched rows */
            set_if_smaller(tmp, (double) thd->variables.max_seeks_for_key);
            if (table->used_keys.is_set(key))
            {
              /* we can use only index tree */
              uint keys_per_block= table->file->block_size/2/
                (keyinfo->key_length+table->file->ref_length)+1;
              tmp = record_count*(tmp+keys_per_block-1)/keys_per_block;
            }
            else
              tmp = record_count*min(tmp,s->worst_seeks);
          }
          else
            tmp = best_time;                    // Do nothing
        }
      } /* not ft_key */
      if (tmp < best_time - records/(double) TIME_FOR_COMPARE)
      {
        best_time= tmp + records/(double) TIME_FOR_COMPARE;
        best= tmp;
        best_records= records;
        best_key= start_key;
        best_max_key_part= max_key_part;
      }
    }
    records= best_records;
  }

  /*
    Don't test table scan if it can't be better.
    Prefer key lookup if we would use the same key for scanning.

    Don't do a table scan on InnoDB tables, if we can read the used
    parts of the row from any of the used index.
    This is because table scans uses index and we would not win
    anything by using a table scan.
  */
  if ((records >= s->found_records || best > s->read_time) &&
      !(s->quick && best_key && s->quick->index == best_key->key &&
        best_max_key_part >= s->table->quick_key_parts[best_key->key]) &&
      !((s->table->file->table_flags() & HA_TABLE_SCAN_ON_INDEX) &&
        ! s->table->used_keys.is_clear_all() && best_key) &&
      !(s->table->force_index && best_key))
  {                                             // Check full join
    ha_rows rnd_records= s->found_records;
    /*
      If there is a restriction on the table, assume that 25% of the
      rows can be skipped on next part.
      This is to force tables that this table depends on before this
      table
    */
    if (found_constraint)
      rnd_records-= rnd_records/4;

    /*
      Range optimizer never proposes a RANGE if it isn't better
      than FULL: so if RANGE is present, it's always preferred to FULL.
      Here we estimate its cost.
    */
    if (s->quick)
    {
      /*
        For each record we:
        - read record range through 'quick'
        - skip rows which does not satisfy WHERE constraints
      */
      tmp= record_count *
        (s->quick->read_time +
         (s->found_records - rnd_records)/(double) TIME_FOR_COMPARE);
    }
    else
    {
      /* Estimate cost of reading table. */
      tmp= s->table->file->scan_time();
unknown's avatar
unknown committed
3653
      if (s->table->map & join->outer_join)     // Can't use join cache
unknown's avatar
af  
unknown committed
3654 3655 3656 3657 3658 3659 3660 3661 3662 3663 3664 3665 3666 3667 3668 3669 3670 3671 3672 3673 3674 3675 3676 3677 3678 3679 3680 3681 3682 3683 3684 3685 3686 3687 3688 3689 3690 3691 3692 3693 3694 3695 3696 3697 3698 3699 3700 3701 3702 3703 3704 3705 3706 3707 3708 3709 3710 3711 3712 3713 3714 3715 3716 3717 3718 3719 3720 3721 3722 3723 3724 3725 3726 3727 3728 3729 3730 3731 3732 3733 3734 3735 3736 3737 3738 3739 3740
      {
        /*
          For each record we have to:
          - read the whole table record 
          - skip rows which does not satisfy join condition
        */
        tmp= record_count *
          (tmp +
           (s->records - rnd_records)/(double) TIME_FOR_COMPARE);
      }
      else
      {
        /* We read the table as many times as join buffer becomes full. */
        tmp*= (1.0 + floor((double) cache_record_length(join,idx) *
                           record_count /
                           (double) thd->variables.join_buff_size));
        /* 
            We don't make full cartesian product between rows in the scanned
           table and existing records because we skip all rows from the
           scanned table, which does not satisfy join condition when 
           we read the table (see flush_cached_records for details). Here we
           take into account cost to read and skip these records.
        */
        tmp+= (s->records - rnd_records)/(double) TIME_FOR_COMPARE;
      }
    }

    /*
      We estimate the cost of evaluating WHERE clause for found records
      as record_count * rnd_records / TIME_FOR_COMPARE. This cost plus
      tmp give us total cost of using TABLE SCAN
    */
    if (best == DBL_MAX ||
        (tmp  + record_count/(double) TIME_FOR_COMPARE*rnd_records <
         best + record_count/(double) TIME_FOR_COMPARE*records))
    {
      /*
        If the table has a range (s->quick is set) make_join_select()
        will ensure that this will be used
      */
      best= tmp;
      records= rows2double(rnd_records);
      best_key= 0;
    }
  }

  /* Update the cost information for the current partial plan */
  join->positions[idx].records_read= records;
  join->positions[idx].read_time=    best;
  join->positions[idx].key=          best_key;
  join->positions[idx].table=        s;

  if (!best_key &&
      idx == join->const_tables &&
      s->table == join->sort_by_table &&
      join->unit->select_limit_cnt >= records)
    join->sort_by_table= (TABLE*) 1;  // Must use temporary table

  DBUG_VOID_RETURN;
}


/*
  Selects and invokes a search strategy for an optimal query plan.

  SYNOPSIS
    choose_plan()
    join        pointer to the structure providing all context info for
                the query
    join_tables set of the tables in the query

  DESCRIPTION
    The function checks user-configurable parameters that control the search
    strategy for an optimal plan, selects the search method and then invokes
    it. Each specific optimization procedure stores the final optimal plan in
    the array 'join->best_positions', and the cost of the plan in
    'join->best_read'.

  RETURN
    None
*/

static void
choose_plan(JOIN *join, table_map join_tables)
{
  uint search_depth= join->thd->variables.optimizer_search_depth;
  uint prune_level=  join->thd->variables.optimizer_prune_level;
3741
  bool straight_join= join->select_options & SELECT_STRAIGHT_JOIN;
unknown's avatar
af  
unknown committed
3742 3743
  DBUG_ENTER("choose_plan");

3744 3745 3746 3747 3748 3749 3750 3751 3752 3753 3754 3755
  /*
    if (SELECT_STRAIGHT_JOIN option is set)
      reorder tables so dependent tables come after tables they depend 
      on, otherwise keep tables in the order they were specified in the query 
    else
      Apply heuristic: pre-sort all access plans with respect to the number of
      records accessed.
  */
  qsort(join->best_ref + join->const_tables, join->tables - join->const_tables,
        sizeof(JOIN_TAB*), straight_join?join_tab_cmp_straight:join_tab_cmp);
  
  if (straight_join)
unknown's avatar
af  
unknown committed
3756 3757 3758 3759 3760 3761 3762 3763 3764 3765 3766 3767 3768 3769 3770 3771 3772 3773 3774 3775 3776 3777
  {
    optimize_straight_join(join, join_tables);
  }
  else
  {
    if (search_depth == MAX_TABLES+2)
    { /*
        TODO: 'MAX_TABLES+2' denotes the old implementation of find_best before
        the greedy version. Will be removed when greedy_search is approved.
      */
      join->best_read= DBL_MAX;
      find_best(join, join_tables, join->const_tables, 1.0, 0.0);
    } 
    else
    {
      if (search_depth == 0)
        /* Automatically determine a reasonable value for 'search_depth' */
        search_depth= determine_search_depth(join);
      greedy_search(join, join_tables, search_depth, prune_level);
    }
  }

3778 3779 3780 3781 3782
  /* 
    Store the cost of this query into a user variable
    Don't update last_query_cost for 'show status' command
  */
  if (join->thd->lex->orig_sql_command != SQLCOM_SHOW_STATUS)
3783
    join->thd->status_var.last_query_cost= join->best_read;
unknown's avatar
af  
unknown committed
3784 3785 3786 3787 3788 3789 3790 3791 3792 3793 3794 3795 3796 3797 3798 3799 3800 3801 3802 3803 3804 3805 3806
  DBUG_VOID_RETURN;
}


/*
  Compare two JOIN_TAB objects based on the number of accessed records.

  SYNOPSIS
    join_tab_cmp()
    ptr1 pointer to first JOIN_TAB object
    ptr2 pointer to second JOIN_TAB object

  RETURN
    1  if first is bigger
    -1 if second is bigger
    0  if equal
*/

static int
join_tab_cmp(const void* ptr1, const void* ptr2)
{
  JOIN_TAB *jt1= *(JOIN_TAB**) ptr1;
  JOIN_TAB *jt2= *(JOIN_TAB**) ptr2;
unknown's avatar
unknown committed
3807 3808 3809 3810 3811

  if (jt1->dependent & jt2->table->map)
    return 1;
  if (jt2->dependent & jt1->table->map)
    return -1;  
unknown's avatar
af  
unknown committed
3812 3813
  if (jt1->found_records > jt2->found_records)
    return 1;
unknown's avatar
unknown committed
3814 3815 3816
  if (jt1->found_records < jt2->found_records)
    return -1; 
  return jt1 > jt2 ? 1 : (jt1 < jt2 ? -1 : 0);
unknown's avatar
af  
unknown committed
3817 3818 3819
}


3820 3821 3822 3823 3824 3825 3826 3827 3828 3829 3830 3831 3832 3833 3834 3835 3836
/* 
  Same as join_tab_cmp, but for use with SELECT_STRAIGHT_JOIN.
*/

static int
join_tab_cmp_straight(const void* ptr1, const void* ptr2)
{
  JOIN_TAB *jt1= *(JOIN_TAB**) ptr1;
  JOIN_TAB *jt2= *(JOIN_TAB**) ptr2;

  if (jt1->dependent & jt2->table->map)
    return 1;
  if (jt2->dependent & jt1->table->map)
    return -1;
  return jt1 > jt2 ? 1 : (jt1 < jt2 ? -1 : 0);
}

unknown's avatar
af  
unknown committed
3837 3838 3839 3840 3841 3842 3843 3844 3845 3846 3847 3848 3849 3850 3851 3852 3853 3854 3855 3856 3857 3858 3859 3860 3861 3862 3863 3864 3865 3866 3867 3868 3869 3870 3871 3872 3873 3874 3875 3876 3877 3878 3879 3880 3881 3882 3883 3884 3885 3886 3887 3888 3889 3890 3891 3892 3893 3894 3895 3896 3897 3898 3899 3900 3901 3902 3903 3904 3905 3906 3907 3908 3909 3910 3911 3912 3913 3914 3915 3916 3917 3918
/*
  Heuristic procedure to automatically guess a reasonable degree of
  exhaustiveness for the greedy search procedure.

  SYNOPSIS
    determine_search_depth()
    join   pointer to the structure providing all context info for the query

  DESCRIPTION
    The procedure estimates the optimization time and selects a search depth
    big enough to result in a near-optimal QEP, that doesn't take too long to
    find. If the number of tables in the query exceeds some constant, then
    search_depth is set to this constant.

  NOTES
    This is an extremely simplistic implementation that serves as a stub for a
    more advanced analysis of the join. Ideally the search depth should be
    determined by learning from previous query optimizations, because it will
    depend on the CPU power (and other factors).

  RETURN
    A positive integer that specifies the search depth (and thus the
    exhaustiveness) of the depth-first search algorithm used by
    'greedy_search'.
*/

static uint
determine_search_depth(JOIN *join)
{
  uint table_count=  join->tables - join->const_tables;
  uint search_depth;
  /* TODO: this value should be determined dynamically, based on statistics: */
  uint max_tables_for_exhaustive_opt= 7;

  if (table_count <= max_tables_for_exhaustive_opt)
    search_depth= table_count+1; // use exhaustive for small number of tables
  else
    /*
      TODO: this value could be determined by some mapping of the form:
      depth : table_count -> [max_tables_for_exhaustive_opt..MAX_EXHAUSTIVE]
    */
    search_depth= max_tables_for_exhaustive_opt; // use greedy search

  return search_depth;
}


/*
  Select the best ways to access the tables in a query without reordering them.

  SYNOPSIS
    optimize_straight_join()
    join          pointer to the structure providing all context info for
                  the query
    join_tables   set of the tables in the query

  DESCRIPTION
    Find the best access paths for each query table and compute their costs
    according to their order in the array 'join->best_ref' (thus without
    reordering the join tables). The function calls sequentially
    'best_access_path' for each table in the query to select the best table
    access method. The final optimal plan is stored in the array
    'join->best_positions', and the corresponding cost in 'join->best_read'.

  NOTES
    This function can be applied to:
    - queries with STRAIGHT_JOIN
    - internally to compute the cost of an arbitrary QEP
    Thus 'optimize_straight_join' can be used at any stage of the query
    optimization process to finalize a QEP as it is.

  RETURN
    None
*/

static void
optimize_straight_join(JOIN *join, table_map join_tables)
{
  JOIN_TAB *s;
  uint idx= join->const_tables;
  double    record_count= 1.0;
  double    read_time=    0.0;
3919
 
unknown's avatar
af  
unknown committed
3920 3921 3922 3923 3924 3925 3926 3927 3928 3929 3930 3931 3932 3933 3934 3935 3936 3937 3938 3939 3940 3941 3942 3943 3944 3945 3946 3947 3948 3949 3950 3951 3952 3953 3954 3955 3956 3957 3958 3959 3960 3961 3962 3963 3964 3965 3966 3967 3968 3969 3970 3971 3972 3973 3974 3975 3976 3977 3978 3979 3980 3981 3982 3983 3984 3985 3986 3987 3988 3989 3990 3991 3992 3993 3994 3995 3996 3997 3998 3999 4000 4001 4002 4003 4004 4005 4006 4007 4008 4009 4010 4011 4012 4013 4014 4015 4016 4017 4018 4019 4020 4021 4022 4023 4024 4025 4026 4027 4028 4029 4030 4031 4032 4033 4034 4035 4036 4037 4038 4039 4040 4041 4042 4043 4044 4045 4046 4047 4048 4049 4050 4051 4052 4053 4054 4055 4056 4057 4058 4059 4060 4061 4062 4063 4064 4065 4066 4067 4068 4069 4070 4071 4072 4073 4074 4075 4076 4077 4078 4079 4080 4081 4082 4083 4084 4085 4086 4087 4088 4089 4090 4091 4092 4093 4094 4095 4096 4097 4098 4099 4100 4101 4102 4103 4104 4105 4106 4107 4108 4109 4110 4111 4112 4113 4114 4115 4116 4117 4118 4119 4120 4121 4122 4123 4124 4125 4126 4127 4128 4129 4130 4131 4132 4133 4134 4135 4136 4137 4138 4139 4140 4141 4142 4143 4144 4145 4146 4147 4148 4149 4150 4151 4152 4153 4154 4155 4156 4157 4158 4159 4160 4161 4162 4163 4164 4165 4166 4167 4168 4169 4170 4171 4172 4173 4174 4175 4176 4177 4178 4179 4180
  for (JOIN_TAB **pos= join->best_ref + idx ; (s= *pos) ; pos++)
  {
    /* Find the best access method from 's' to the current partial plan */
    best_access_path(join, s, join->thd, join_tables, idx, record_count, read_time);
    /* compute the cost of the new plan extended with 's' */
    record_count*= join->positions[idx].records_read;
    read_time+=    join->positions[idx].read_time;
    join_tables&= ~(s->table->map);
    ++idx;
  }

  read_time+= record_count / (double) TIME_FOR_COMPARE;
  if (join->sort_by_table &&
      join->sort_by_table != join->positions[join->const_tables].table->table)
    read_time+= record_count;  // We have to make a temp table
  memcpy((gptr) join->best_positions, (gptr) join->positions,
         sizeof(POSITION)*idx);
  join->best_read= read_time;
}


/*
  Find a good, possibly optimal, query execution plan (QEP) by a greedy search.

  SYNOPSIS
    join             pointer to the structure providing all context info
                     for the query
    remaining_tables set of tables not included into the partial plan yet
    search_depth     controlls the exhaustiveness of the search
    prune_level      the pruning heuristics that should be applied during
                     search

  DESCRIPTION
    The search procedure uses a hybrid greedy/exhaustive search with controlled
    exhaustiveness. The search is performed in N = card(remaining_tables)
    steps. Each step evaluates how promising is each of the unoptimized tables,
    selects the most promising table, and extends the current partial QEP with
    that table.  Currenly the most 'promising' table is the one with least
    expensive extension.
    There are two extreme cases:
    1. When (card(remaining_tables) < search_depth), the estimate finds the best
       complete continuation of the partial QEP. This continuation can be
       used directly as a result of the search.
    2. When (search_depth == 1) the 'best_extension_by_limited_search'
       consideres the extension of the current QEP with each of the remaining
       unoptimized tables.
    All other cases are in-between these two extremes. Thus the parameter
    'search_depth' controlls the exhaustiveness of the search. The higher the
    value, the longer the optimizaton time and possibly the better the
    resulting plan. The lower the value, the fewer alternative plans are
    estimated, but the more likely to get a bad QEP.

    All intermediate and final results of the procedure are stored in 'join':
    join->positions      modified for every partial QEP that is explored
    join->best_positions modified for the current best complete QEP
    join->best_read      modified for the current best complete QEP
    join->best_ref       might be partially reordered
    The final optimal plan is stored in 'join->best_positions', and its
    corresponding cost in 'join->best_read'.

  NOTES
    The following pseudocode describes the algorithm of 'greedy_search':

    procedure greedy_search
    input: remaining_tables
    output: pplan;
    {
      pplan = <>;
      do {
        (t, a) = best_extension(pplan, remaining_tables);
        pplan = concat(pplan, (t, a));
        remaining_tables = remaining_tables - t;
      } while (remaining_tables != {})
      return pplan;
    }

    where 'best_extension' is a placeholder for a procedure that selects the
    most "promising" of all tables in 'remaining_tables'.
    Currently this estimate is performed by calling
    'best_extension_by_limited_search' to evaluate all extensions of the
    current QEP of size 'search_depth', thus the complexity of 'greedy_search'
    mainly depends on that of 'best_extension_by_limited_search'.

    If 'best_extension()' == 'best_extension_by_limited_search()', then the
    worst-case complexity of this algorithm is <=
    O(N*N^search_depth/search_depth). When serch_depth >= N, then the
    complexity of greedy_search is O(N!).

    In the future, 'greedy_search' might be extended to support other
    implementations of 'best_extension', e.g. some simpler quadratic procedure.

  RETURN
    None
*/

static void
greedy_search(JOIN      *join,
              table_map remaining_tables,
              uint      search_depth,
              uint      prune_level)
{
  double    record_count= 1.0;
  double    read_time=    0.0;
  uint      idx= join->const_tables; // index into 'join->best_ref'
  uint      best_idx;
  uint      rem_size;    // cardinality of remaining_tables
  POSITION  best_pos;
  JOIN_TAB  *best_table; // the next plan node to be added to the curr QEP

  DBUG_ENTER("greedy_search");

  /* number of tables that remain to be optimized */
  rem_size= my_count_bits(remaining_tables);

  do {
    /* Find the extension of the current QEP with the lowest cost */
    join->best_read= DBL_MAX;
    best_extension_by_limited_search(join, remaining_tables, idx, record_count,
                                     read_time, search_depth, prune_level);

    if (rem_size <= search_depth)
    {
      /*
        'join->best_positions' contains a complete optimal extension of the
        current partial QEP.
      */
      DBUG_EXECUTE("opt", print_plan(join, read_time, record_count,
                                     join->tables, "optimal"););
      DBUG_VOID_RETURN;
    }

    /* select the first table in the optimal extension as most promising */
    best_pos= join->best_positions[idx];
    best_table= best_pos.table;
    /*
      Each subsequent loop of 'best_extension_by_limited_search' uses
      'join->positions' for cost estimates, therefore we have to update its
      value.
    */
    join->positions[idx]= best_pos;

    /* find the position of 'best_table' in 'join->best_ref' */
    best_idx= idx;
    JOIN_TAB *pos= join->best_ref[best_idx];
    while (pos && best_table != pos)
      pos= join->best_ref[++best_idx];
    DBUG_ASSERT((pos != NULL)); // should always find 'best_table'
    /* move 'best_table' at the first free position in the array of joins */
    swap_variables(JOIN_TAB*, join->best_ref[idx], join->best_ref[best_idx]);

    /* compute the cost of the new plan extended with 'best_table' */
    record_count*= join->positions[idx].records_read;
    read_time+=    join->positions[idx].read_time;

    remaining_tables&= ~(best_table->table->map);
    --rem_size;
    ++idx;

    DBUG_EXECUTE("opt",
                 print_plan(join, read_time, record_count, idx, "extended"););
  } while (TRUE);
}


/*
  Find a good, possibly optimal, query execution plan (QEP) by a possibly
  exhaustive search.

  SYNOPSIS
    best_extension_by_limited_search()
    join             pointer to the structure providing all context info for
                     the query
    remaining_tables set of tables not included into the partial plan yet
    idx              length of the partial QEP in 'join->positions';
                     since a depth-first search is used, also corresponds to
                     the current depth of the search tree;
                     also an index in the array 'join->best_ref';
    record_count     estimate for the number of records returned by the best
                     partial plan
    read_time        the cost of the best partial plan
    search_depth     maximum depth of the recursion and thus size of the found
                     optimal plan (0 < search_depth <= join->tables+1).
    prune_level      pruning heuristics that should be applied during optimization
                     (values: 0 = EXHAUSTIVE, 1 = PRUNE_BY_TIME_OR_ROWS)

  DESCRIPTION
    The procedure searches for the optimal ordering of the query tables in set
    'remaining_tables' of size N, and the corresponding optimal access paths to each
    table. The choice of a table order and an access path for each table
    constitutes a query execution plan (QEP) that fully specifies how to
    execute the query.
   
    The maximal size of the found plan is controlled by the parameter
    'search_depth'. When search_depth == N, the resulting plan is complete and
    can be used directly as a QEP. If search_depth < N, the found plan consists
    of only some of the query tables. Such "partial" optimal plans are useful
    only as input to query optimization procedures, and cannot be used directly
    to execute a query.

    The algorithm begins with an empty partial plan stored in 'join->positions'
    and a set of N tables - 'remaining_tables'. Each step of the algorithm
    evaluates the cost of the partial plan extended by all access plans for
    each of the relations in 'remaining_tables', expands the current partial
    plan with the access plan that results in lowest cost of the expanded
    partial plan, and removes the corresponding relation from
    'remaining_tables'. The algorithm continues until it either constructs a
    complete optimal plan, or constructs an optimal plartial plan with size =
    search_depth.

    The final optimal plan is stored in 'join->best_positions'. The
    corresponding cost of the optimal plan is in 'join->best_read'.

  NOTES
    The procedure uses a recursive depth-first search where the depth of the
    recursion (and thus the exhaustiveness of the search) is controlled by the
    parameter 'search_depth'.

    The pseudocode below describes the algorithm of
    'best_extension_by_limited_search'. The worst-case complexity of this
    algorithm is O(N*N^search_depth/search_depth). When serch_depth >= N, then
    the complexity of greedy_search is O(N!).

    procedure best_extension_by_limited_search(
      pplan in,             // in, partial plan of tables-joined-so-far
      pplan_cost,           // in, cost of pplan
      remaining_tables,     // in, set of tables not referenced in pplan
      best_plan_so_far,     // in/out, best plan found so far
      best_plan_so_far_cost,// in/out, cost of best_plan_so_far
      search_depth)         // in, maximum size of the plans being considered
    {
      for each table T from remaining_tables
      {
        // Calculate the cost of using table T as above
        cost = complex-series-of-calculations;

        // Add the cost to the cost so far.
        pplan_cost+= cost;

        if (pplan_cost >= best_plan_so_far_cost)
          // pplan_cost already too great, stop search
          continue;

        pplan= expand pplan by best_access_method;
        remaining_tables= remaining_tables - table T;
        if (remaining_tables is not an empty set
            and
            search_depth > 1)
        {
          best_extension_by_limited_search(pplan, pplan_cost,
                                           remaining_tables,
                                           best_plan_so_far,
                                           best_plan_so_far_cost,
                                           search_depth - 1);
        }
        else
        {
          best_plan_so_far_cost= pplan_cost;
          best_plan_so_far= pplan;
        }
      }
    }
unknown's avatar
unknown committed
4181

unknown's avatar
af  
unknown committed
4182 4183 4184 4185 4186 4187 4188 4189
  IMPLEMENTATION
    When 'best_extension_by_limited_search' is called for the first time,
    'join->best_read' must be set to the largest possible value (e.g. DBL_MAX).
    The actual implementation provides a way to optionally use pruning
    heuristic (controlled by the parameter 'prune_level') to reduce the search
    space by skipping some partial plans.
    The parameter 'search_depth' provides control over the recursion
    depth, and thus the size of the resulting optimal plan.
unknown's avatar
unknown committed
4190

unknown's avatar
af  
unknown committed
4191 4192 4193
  RETURN
    None
*/
unknown's avatar
unknown committed
4194 4195

static void
unknown's avatar
af  
unknown committed
4196 4197 4198 4199 4200 4201 4202
best_extension_by_limited_search(JOIN      *join,
                                 table_map remaining_tables,
                                 uint      idx,
                                 double    record_count,
                                 double    read_time,
                                 uint      search_depth,
                                 uint      prune_level)
unknown's avatar
unknown committed
4203
{
unknown's avatar
af  
unknown committed
4204 4205 4206
  THD *thd= join->thd;
  if (thd->killed)  // Abort
    return;
unknown's avatar
unknown committed
4207

unknown's avatar
af  
unknown committed
4208 4209 4210 4211 4212 4213 4214 4215 4216 4217 4218 4219 4220 4221
  DBUG_ENTER("best_extension_by_limited_search");

  /* 
     'join' is a partial plan with lower cost than the best plan so far,
     so continue expanding it further with the tables in 'remaining_tables'.
  */
  JOIN_TAB *s;
  double best_record_count= DBL_MAX;
  double best_read_time=    DBL_MAX;

  DBUG_EXECUTE("opt",
               print_plan(join, read_time, record_count, idx, "part_plan"););

  for (JOIN_TAB **pos= join->best_ref + idx ; (s= *pos) ; pos++)
unknown's avatar
unknown committed
4222
  {
unknown's avatar
af  
unknown committed
4223 4224 4225 4226
    table_map real_table_bit= s->table->map;
    if ((remaining_tables & real_table_bit) && !(remaining_tables & s->dependent))
    {
      double current_record_count, current_read_time;
unknown's avatar
unknown committed
4227

unknown's avatar
af  
unknown committed
4228 4229 4230 4231 4232
      /* Find the best access method from 's' to the current partial plan */
      best_access_path(join, s, thd, remaining_tables, idx, record_count, read_time);
      /* Compute the cost of extending the plan with 's' */
      current_record_count= record_count * join->positions[idx].records_read;
      current_read_time=    read_time + join->positions[idx].read_time;
unknown's avatar
unknown committed
4233

unknown's avatar
af  
unknown committed
4234 4235 4236 4237 4238 4239 4240 4241 4242 4243 4244 4245 4246 4247 4248 4249 4250 4251 4252 4253 4254 4255 4256 4257 4258 4259 4260 4261 4262 4263 4264 4265 4266 4267 4268 4269 4270 4271 4272 4273 4274 4275 4276 4277 4278 4279 4280 4281 4282 4283 4284 4285 4286 4287 4288 4289 4290 4291 4292 4293 4294 4295 4296 4297 4298 4299
      /* Expand only partial plans with lower cost than the best QEP so far */
      if ((current_read_time +
           current_record_count / (double) TIME_FOR_COMPARE) >= join->best_read)
      {
        DBUG_EXECUTE("opt", print_plan(join, read_time, record_count, idx,
                                       "prune_by_cost"););
        continue;
      }

      /*
        Prune some less promising partial plans. This heuristic may miss
        the optimal QEPs, thus it results in a non-exhaustive search.
      */
      if (prune_level == 1)
      {
        if (best_record_count > current_record_count ||
            best_read_time > current_read_time ||
            idx == join->const_tables &&  // 's' is the first table in the QEP
            s->table == join->sort_by_table)
        {
          if (best_record_count >= current_record_count &&
              best_read_time >= current_read_time &&
              /* TODO: What is the reasoning behind this condition? */
              (!(s->key_dependent & remaining_tables) ||
               join->positions[idx].records_read < 2.0))
          {
            best_record_count= current_record_count;
            best_read_time=    current_read_time;
          }
        }
        else
        {
          DBUG_EXECUTE("opt", print_plan(join, read_time, record_count, idx,
                                         "pruned_by_heuristic"););
          continue;
        }
      }

      if ( (search_depth > 1) && (remaining_tables & ~real_table_bit) )
      { /* Recursively expand the current partial plan */
        swap_variables(JOIN_TAB*, join->best_ref[idx], *pos);
        best_extension_by_limited_search(join,
                                         remaining_tables & ~real_table_bit,
                                         idx + 1,
                                         current_record_count,
                                         current_read_time,
                                         search_depth - 1,
                                         prune_level);
        if (thd->killed)
          DBUG_VOID_RETURN;
        swap_variables(JOIN_TAB*, join->best_ref[idx], *pos);
      }
      else
      { /*
          'join' is either the best partial QEP with 'search_depth' relations,
          or the best complete QEP so far, whichever is smaller.
        */
        current_read_time+= current_record_count / (double) TIME_FOR_COMPARE;
        if (join->sort_by_table &&
            join->sort_by_table != join->positions[join->const_tables].table->table)
          /* We have to make a temp table */
          current_read_time+= current_record_count;
        if ((search_depth == 1) || (current_read_time < join->best_read))
        {
          memcpy((gptr) join->best_positions, (gptr) join->positions,
                 sizeof(POSITION) * (idx + 1));
unknown's avatar
unknown committed
4300
          join->best_read= current_read_time - 0.001;
unknown's avatar
af  
unknown committed
4301 4302 4303 4304 4305 4306
        }
        DBUG_EXECUTE("opt",
                     print_plan(join, current_read_time, current_record_count, idx, "full_plan"););
      }
    }
  }
unknown's avatar
unknown committed
4307 4308 4309 4310
  DBUG_VOID_RETURN;
}


unknown's avatar
af  
unknown committed
4311 4312 4313 4314
/*
  TODO: this function is here only temporarily until 'greedy_search' is
  tested and accepted.
*/
unknown's avatar
unknown committed
4315 4316 4317 4318
static void
find_best(JOIN *join,table_map rest_tables,uint idx,double record_count,
	  double read_time)
{
4319
  ha_rows rec;
unknown's avatar
unknown committed
4320
  double tmp;
unknown's avatar
unknown committed
4321
  THD *thd= join->thd;
unknown's avatar
unknown committed
4322 4323 4324 4325 4326 4327 4328 4329

  if (!rest_tables)
  {
    DBUG_PRINT("best",("read_time: %g  record_count: %g",read_time,
		       record_count));

    read_time+=record_count/(double) TIME_FOR_COMPARE;
    if (join->sort_by_table &&
unknown's avatar
af  
unknown committed
4330 4331
	join->sort_by_table !=
	join->positions[join->const_tables].table->table)
unknown's avatar
unknown committed
4332 4333 4334 4335 4336
      read_time+=record_count;			// We have to make a temp table
    if (read_time < join->best_read)
    {
      memcpy((gptr) join->best_positions,(gptr) join->positions,
	     sizeof(POSITION)*idx);
unknown's avatar
unknown committed
4337
      join->best_read= read_time - 0.001;
unknown's avatar
unknown committed
4338 4339 4340 4341 4342 4343 4344 4345 4346 4347 4348 4349 4350 4351 4352 4353
    }
    return;
  }
  if (read_time+record_count/(double) TIME_FOR_COMPARE >= join->best_read)
    return;					/* Found better before */

  JOIN_TAB *s;
  double best_record_count=DBL_MAX,best_read_time=DBL_MAX;
  for (JOIN_TAB **pos=join->best_ref+idx ; (s=*pos) ; pos++)
  {
    table_map real_table_bit=s->table->map;
    if ((rest_tables & real_table_bit) && !(rest_tables & s->dependent))
    {
      double best,best_time,records;
      best=best_time=records=DBL_MAX;
      KEYUSE *best_key=0;
4354
      uint best_max_key_part=0;
4355
      my_bool found_constraint= 0;
unknown's avatar
unknown committed
4356 4357 4358 4359 4360 4361

      if (s->keyuse)
      {						/* Use key if possible */
	TABLE *table=s->table;
	KEYUSE *keyuse,*start_key=0;
	double best_records=DBL_MAX;
4362
	uint max_key_part=0;
unknown's avatar
unknown committed
4363 4364

	/* Test how we can use keys */
4365
	rec= s->records/MATCHING_ROWS_IN_OTHER_TABLE;  // Assumed records/key
unknown's avatar
unknown committed
4366 4367
	for (keyuse=s->keyuse ; keyuse->table == table ;)
	{
4368
	  key_part_map found_part=0;
unknown's avatar
unknown committed
4369 4370 4371 4372
	  table_map found_ref=0;
	  uint key=keyuse->key;
	  KEY *keyinfo=table->key_info+key;
          bool ft_key=(keyuse->keypart == FT_KEYPART);
4373
	  uint found_ref_or_null= 0;
unknown's avatar
unknown committed
4374

4375
	  /* Calculate how many key segments of the current key we can use */
unknown's avatar
unknown committed
4376 4377 4378 4379
	  start_key=keyuse;
	  do
	  {
            uint keypart=keyuse->keypart;
unknown's avatar
af  
unknown committed
4380 4381
            table_map best_part_found_ref= 0;
            double best_prev_record_reads= DBL_MAX;
unknown's avatar
unknown committed
4382 4383
	    do
	    {
4384 4385 4386 4387
	      if (!(rest_tables & keyuse->used_tables) &&
		  !(found_ref_or_null & keyuse->optimize))
	      {
		found_part|=keyuse->keypart_map;
unknown's avatar
af  
unknown committed
4388 4389 4390 4391 4392 4393 4394 4395
                double tmp= prev_record_reads(join,
					      (found_ref |
					       keyuse->used_tables));
                if (tmp < best_prev_record_reads)
                {
                  best_part_found_ref= keyuse->used_tables;
                  best_prev_record_reads= tmp;
                }
4396 4397
		if (rec > keyuse->ref_table_rows)
		  rec= keyuse->ref_table_rows;
unknown's avatar
af  
unknown committed
4398 4399
		/*
		  If there is one 'key_column IS NULL' expression, we can
4400
		  use this ref_or_null optimisation of this field
unknown's avatar
af  
unknown committed
4401 4402 4403
		*/
		found_ref_or_null|= (keyuse->optimize &
				     KEY_OPTIMIZE_REF_OR_NULL);
unknown's avatar
unknown committed
4404 4405 4406 4407
              }
	      keyuse++;
	    } while (keyuse->table == table && keyuse->key == key &&
		     keyuse->keypart == keypart);
unknown's avatar
af  
unknown committed
4408
	    found_ref|= best_part_found_ref;
unknown's avatar
unknown committed
4409 4410 4411
	  } while (keyuse->table == table && keyuse->key == key);

	  /*
4412
	    Assume that that each key matches a proportional part of table.
unknown's avatar
unknown committed
4413 4414 4415
	  */
          if (!found_part && !ft_key)
	    continue;				// Nothing usable found
4416 4417
	  if (rec < MATCHING_ROWS_IN_OTHER_TABLE)
	    rec= MATCHING_ROWS_IN_OTHER_TABLE;	// Fix for small tables
unknown's avatar
unknown committed
4418 4419

          /*
4420
	    ft-keys require special treatment
unknown's avatar
unknown committed
4421 4422 4423 4424
          */
          if (ft_key)
          {
            /*
4425 4426
	      Really, there should be records=0.0 (yes!)
	      but 1.0 would be probably safer
unknown's avatar
unknown committed
4427 4428 4429 4430 4431 4432
            */
            tmp=prev_record_reads(join,found_ref);
            records=1.0;
          }
          else
          {
4433
	  found_constraint= 1;
unknown's avatar
unknown committed
4434
	  /*
4435
	    Check if we found full key
unknown's avatar
unknown committed
4436
	  */
4437 4438
	  if (found_part == PREV_BITS(uint,keyinfo->key_parts) &&
	      !found_ref_or_null)
unknown's avatar
unknown committed
4439
	  {				/* use eq key */
4440
	    max_key_part= (uint) ~0;
4441 4442
	    if ((keyinfo->flags & (HA_NOSAME | HA_NULL_PART_KEY |
				   HA_END_SPACE_KEY)) == HA_NOSAME)
unknown's avatar
unknown committed
4443 4444 4445 4446 4447 4448
	    {
	      tmp=prev_record_reads(join,found_ref);
	      records=1.0;
	    }
	    else
	    {
4449 4450
	      if (!found_ref)
	      {					// We found a const key
4451
		if (table->quick_keys.is_set(key))
unknown's avatar
unknown committed
4452 4453
		  records= (double) table->quick_rows[key];
		else
unknown's avatar
unknown committed
4454 4455 4456 4457
		{
		  /* quick_range couldn't use key! */
		  records= (double) s->records/rec;
		}
unknown's avatar
unknown committed
4458 4459 4460 4461 4462 4463 4464 4465
	      }
	      else
	      {
		if (!(records=keyinfo->rec_per_key[keyinfo->key_parts-1]))
		{				// Prefere longer keys
		  records=
		    ((double) s->records / (double) rec *
		     (1.0 +
4466 4467
		      ((double) (table->s->max_key_length-keyinfo->key_length) /
		       (double) table->s->max_key_length)));
unknown's avatar
unknown committed
4468 4469 4470 4471
		  if (records < 2.0)
		    records=2.0;		// Can't be as good as a unique
		}
	      }
4472 4473 4474
	      /* Limit the number of matched rows */
	      tmp= records;
	      set_if_smaller(tmp, (double) thd->variables.max_seeks_for_key);
4475
	      if (table->used_keys.is_set(key))
unknown's avatar
unknown committed
4476 4477 4478
	      {
		/* we can use only index tree */
		uint keys_per_block= table->file->block_size/2/
unknown's avatar
unknown committed
4479
		  (keyinfo->key_length+table->file->ref_length)+1;
4480
		tmp=record_count*(tmp+keys_per_block-1)/keys_per_block;
unknown's avatar
unknown committed
4481 4482
	      }
	      else
4483
		tmp=record_count*min(tmp,s->worst_seeks);
unknown's avatar
unknown committed
4484 4485 4486 4487 4488
	    }
	  }
	  else
	  {
	    /*
4489 4490 4491
	      Use as much key-parts as possible and a uniq key is better
	      than a not unique key
	      Set tmp to (previous record count) * (records / combination)
unknown's avatar
unknown committed
4492
	    */
4493
	    if ((found_part & 1) &&
4494
		(!(table->file->index_flags(key,0,0) & HA_ONLY_WHOLE_INDEX) ||
4495
		 found_part == PREV_BITS(uint,keyinfo->key_parts)))
unknown's avatar
unknown committed
4496
	    {
4497
	      max_key_part=max_part_bit(found_part);
4498 4499 4500 4501
	      /*
		Check if quick_range could determinate how many rows we
		will match
	      */
4502
	      if (table->quick_keys.is_set(key) &&
unknown's avatar
af  
unknown committed
4503
		  table->quick_key_parts[key] == max_key_part)
unknown's avatar
unknown committed
4504 4505 4506 4507 4508 4509 4510 4511 4512
		tmp=records= (double) table->quick_rows[key];
	      else
	      {
		/* Check if we have statistic about the distribution */
		if ((records=keyinfo->rec_per_key[max_key_part-1]))
		  tmp=records;
		else
		{
		  /*
4513
		    Assume that the first key part matches 1% of the file
unknown's avatar
unknown committed
4514
		    and that the whole key matches 10 (duplicates) or 1
4515 4516 4517 4518 4519
		    (unique) records.
		    Assume also that more key matches proportionally more
		    records
		    This gives the formula:
		    records= (x * (b-a) + a*c-b)/(c-1)
4520

4521 4522 4523 4524
		    b = records matched by whole key
		    a = records matched by first key part (10% of all records?)
		    c = number of key parts in key
		    x = used key parts (1 <= x <= c)
unknown's avatar
unknown committed
4525 4526
		  */
		  double rec_per_key;
4527 4528 4529
                  rec_per_key= keyinfo->rec_per_key[keyinfo->key_parts-1] ?
		    (double) keyinfo->rec_per_key[keyinfo->key_parts-1] :
		    (double) s->records/rec+1;   
unknown's avatar
unknown committed
4530 4531 4532 4533 4534 4535 4536 4537 4538 4539 4540 4541 4542 4543
		  if (!s->records)
		    tmp=0;
		  else if (rec_per_key/(double) s->records >= 0.01)
		    tmp=rec_per_key;
		  else
		  {
		    double a=s->records*0.01;
		    tmp=(max_key_part * (rec_per_key - a) +
			 a*keyinfo->key_parts - rec_per_key)/
		      (keyinfo->key_parts-1);
		    set_if_bigger(tmp,1.0);
		  }
		  records=(ulong) tmp;
		}
unknown's avatar
af  
unknown committed
4544 4545 4546 4547 4548 4549 4550 4551 4552
		/*
		  If quick_select was used on a part of this key, we know
		  the maximum number of rows that the key can match.
		*/
		if (table->quick_keys.is_set(key) &&
		    table->quick_key_parts[key] <= max_key_part &&
		    records > (double) table->quick_rows[key])
		  tmp= records= (double) table->quick_rows[key];
		else if (found_ref_or_null)
4553 4554 4555 4556 4557
		{
		  /* We need to do two key searches to find key */
		  tmp*= 2.0;
		  records*= 2.0;
		}
unknown's avatar
unknown committed
4558
	      }
4559 4560
	      /* Limit the number of matched rows */
	      set_if_smaller(tmp, (double) thd->variables.max_seeks_for_key);
4561
	      if (table->used_keys.is_set(key))
unknown's avatar
unknown committed
4562 4563 4564
	      {
		/* we can use only index tree */
		uint keys_per_block= table->file->block_size/2/
unknown's avatar
unknown committed
4565
		  (keyinfo->key_length+table->file->ref_length)+1;
unknown's avatar
unknown committed
4566 4567 4568 4569 4570 4571 4572 4573
		tmp=record_count*(tmp+keys_per_block-1)/keys_per_block;
	      }
	      else
		tmp=record_count*min(tmp,s->worst_seeks);
	    }
	    else
	      tmp=best_time;			// Do nothing
	  }
4574
          } /* not ft_key */
unknown's avatar
unknown committed
4575 4576 4577 4578 4579 4580
	  if (tmp < best_time - records/(double) TIME_FOR_COMPARE)
	  {
	    best_time=tmp + records/(double) TIME_FOR_COMPARE;
	    best=tmp;
	    best_records=records;
	    best_key=start_key;
4581
	    best_max_key_part=max_key_part;
unknown's avatar
unknown committed
4582 4583 4584 4585
	  }
	}
	records=best_records;
      }
4586 4587 4588 4589

      /*
	Don't test table scan if it can't be better.
	Prefer key lookup if we would use the same key for scanning.
4590 4591 4592 4593 4594

	Don't do a table scan on InnoDB tables, if we can read the used
	parts of the row from any of the used index.
	This is because table scans uses index and we would not win
	anything by using a table scan.
4595 4596 4597
      */
      if ((records >= s->found_records || best > s->read_time) &&
	  !(s->quick && best_key && s->quick->index == best_key->key &&
4598
	    best_max_key_part >= s->table->quick_key_parts[best_key->key]) &&
4599
	  !((s->table->file->table_flags() & HA_TABLE_SCAN_ON_INDEX) &&
4600
	    ! s->table->used_keys.is_clear_all() && best_key) &&
4601
	  !(s->table->force_index && best_key))
unknown's avatar
unknown committed
4602
      {						// Check full join
4603 4604 4605 4606 4607 4608 4609 4610 4611 4612
        ha_rows rnd_records= s->found_records;
        /*
          If there is a restriction on the table, assume that 25% of the
          rows can be skipped on next part.
          This is to force tables that this table depends on before this
          table
        */
        if (found_constraint)
          rnd_records-= rnd_records/4;

4613 4614 4615 4616 4617 4618
        /*
          Range optimizer never proposes a RANGE if it isn't better
          than FULL: so if RANGE is present, it's always preferred to FULL.
          Here we estimate its cost.
        */
        if (s->quick)
4619
        {
4620 4621 4622 4623 4624
          /*
            For each record we:
             - read record range through 'quick'
             - skip rows which does not satisfy WHERE constraints
           */
4625
          tmp= record_count *
4626 4627
               (s->quick->read_time +
               (s->found_records - rnd_records)/(double) TIME_FOR_COMPARE);
4628 4629 4630
        }
        else
        {
4631 4632
          /* Estimate cost of reading table. */
          tmp= s->table->file->scan_time();
4633
          if (s->table->map  & join->outer_join)      // Can't use join cache
4634 4635 4636 4637 4638 4639 4640 4641 4642 4643 4644 4645 4646 4647 4648 4649 4650 4651 4652 4653 4654 4655 4656 4657 4658
          {
            /*
              For each record we have to:
              - read the whole table record 
              - skip rows which does not satisfy join condition
            */
            tmp= record_count *
                 (tmp +     
                 (s->records - rnd_records)/(double) TIME_FOR_COMPARE);
          }
          else
          {
            /* We read the table as many times as join buffer becomes full. */
            tmp*= (1.0 + floor((double) cache_record_length(join,idx) *
                               record_count /
                               (double) thd->variables.join_buff_size));
            /* 
              We don't make full cartesian product between rows in the scanned
              table and existing records because we skip all rows from the
              scanned table, which does not satisfy join condition when 
              we read the table (see flush_cached_records for details). Here we
              take into account cost to read and skip these records.
            */
            tmp+= (s->records - rnd_records)/(double) TIME_FOR_COMPARE;
          }
4659
        }
4660

4661
        /*
4662
          We estimate the cost of evaluating WHERE clause for found records
4663
          as record_count * rnd_records / TIME_FOR_COMPARE. This cost plus
4664
          tmp give us total cost of using TABLE SCAN
unknown's avatar
unknown committed
4665
        */
unknown's avatar
unknown committed
4666
	if (best == DBL_MAX ||
4667
	    (tmp  + record_count/(double) TIME_FOR_COMPARE*rnd_records <
unknown's avatar
unknown committed
4668 4669
	     best + record_count/(double) TIME_FOR_COMPARE*records))
	{
4670 4671 4672 4673
	  /*
	    If the table has a range (s->quick is set) make_join_select()
	    will ensure that this will be used
	  */
unknown's avatar
unknown committed
4674
	  best=tmp;
4675
	  records= rows2double(rnd_records);
unknown's avatar
unknown committed
4676 4677 4678
	  best_key=0;
	}
      }
4679
      join->positions[idx].records_read= records;
unknown's avatar
unknown committed
4680 4681 4682
      join->positions[idx].key=best_key;
      join->positions[idx].table= s;
      if (!best_key && idx == join->const_tables &&
unknown's avatar
unknown committed
4683
	  s->table == join->sort_by_table &&
4684
	  join->unit->select_limit_cnt >= records)
unknown's avatar
unknown committed
4685 4686 4687 4688 4689 4690 4691 4692 4693 4694 4695 4696 4697 4698 4699 4700 4701 4702 4703
	join->sort_by_table= (TABLE*) 1;	// Must use temporary table

     /*
	Go to the next level only if there hasn't been a better key on
	this level! This will cut down the search for a lot simple cases!
       */
      double current_record_count=record_count*records;
      double current_read_time=read_time+best;
      if (best_record_count > current_record_count ||
	  best_read_time > current_read_time ||
	  idx == join->const_tables && s->table == join->sort_by_table)
      {
	if (best_record_count >= current_record_count &&
	    best_read_time >= current_read_time &&
	    (!(s->key_dependent & rest_tables) || records < 2.0))
	{
	  best_record_count=current_record_count;
	  best_read_time=current_read_time;
	}
unknown's avatar
af  
unknown committed
4704
	swap_variables(JOIN_TAB*, join->best_ref[idx], *pos);
unknown's avatar
unknown committed
4705 4706
	find_best(join,rest_tables & ~real_table_bit,idx+1,
		  current_record_count,current_read_time);
unknown's avatar
unknown committed
4707 4708
        if (thd->killed)
          return;
unknown's avatar
af  
unknown committed
4709
	swap_variables(JOIN_TAB*, join->best_ref[idx], *pos);
unknown's avatar
unknown committed
4710 4711 4712 4713 4714 4715 4716 4717 4718
      }
      if (join->select_options & SELECT_STRAIGHT_JOIN)
	break;				// Don't test all combinations
    }
  }
}


/*
4719
  Find how much space the prevous read not const tables takes in cache
unknown's avatar
unknown committed
4720 4721
*/

4722 4723 4724 4725 4726 4727 4728 4729 4730 4731 4732 4733 4734 4735 4736 4737 4738 4739 4740 4741
static void calc_used_field_length(THD *thd, JOIN_TAB *join_tab)
{
  uint null_fields,blobs,fields,rec_length;
  null_fields=blobs=fields=rec_length=0;

  Field **f_ptr,*field;
  for (f_ptr=join_tab->table->field ; (field= *f_ptr) ; f_ptr++)
  {
    if (field->query_id == thd->query_id)
    {
      uint flags=field->flags;
      fields++;
      rec_length+=field->pack_length();
      if (flags & BLOB_FLAG)
	blobs++;
      if (!(flags & NOT_NULL_FLAG))
	null_fields++;
    }
  }
  if (null_fields)
4742
    rec_length+=(join_tab->table->s->null_fields+7)/8;
4743 4744 4745 4746 4747
  if (join_tab->table->maybe_null)
    rec_length+=sizeof(my_bool);
  if (blobs)
  {
    uint blob_length=(uint) (join_tab->table->file->mean_rec_length-
4748
			     (join_tab->table->s->reclength- rec_length));
4749 4750 4751 4752 4753 4754 4755 4756
    rec_length+=(uint) max(4,blob_length);
  }
  join_tab->used_fields=fields;
  join_tab->used_fieldlength=rec_length;
  join_tab->used_blobs=blobs;
}


unknown's avatar
unknown committed
4757 4758 4759
static uint
cache_record_length(JOIN *join,uint idx)
{
4760
  uint length=0;
unknown's avatar
unknown committed
4761
  JOIN_TAB **pos,**end;
4762
  THD *thd=join->thd;
unknown's avatar
unknown committed
4763 4764 4765 4766 4767 4768

  for (pos=join->best_ref+join->const_tables,end=join->best_ref+idx ;
       pos != end ;
       pos++)
  {
    JOIN_TAB *join_tab= *pos;
4769 4770
    if (!join_tab->used_fieldlength)		/* Not calced yet */
      calc_used_field_length(thd, join_tab);
unknown's avatar
unknown committed
4771 4772 4773 4774 4775 4776 4777 4778 4779 4780
    length+=join_tab->used_fieldlength;
  }
  return length;
}


static double
prev_record_reads(JOIN *join,table_map found_ref)
{
  double found=1.0;
unknown's avatar
unknown committed
4781
  found_ref&= ~OUTER_REF_TABLE_BIT;
unknown's avatar
unknown committed
4782 4783 4784 4785 4786 4787 4788 4789 4790 4791 4792 4793 4794
  for (POSITION *pos=join->positions ; found_ref ; pos++)
  {
    if (pos->table->table->map & found_ref)
    {
      found_ref&= ~pos->table->table->map;
      found*=pos->records_read;
    }
  }
  return found;
}


/*****************************************************************************
4795
  Set up join struct according to best position.
unknown's avatar
unknown committed
4796 4797 4798 4799 4800
*****************************************************************************/

static bool
get_best_combination(JOIN *join)
{
4801
  uint i,tablenr;
unknown's avatar
unknown committed
4802 4803 4804 4805
  table_map used_tables;
  JOIN_TAB *join_tab,*j;
  KEYUSE *keyuse;
  uint table_count;
4806
  THD *thd=join->thd;
unknown's avatar
unknown committed
4807
  DBUG_ENTER("get_best_combination");
unknown's avatar
unknown committed
4808 4809 4810

  table_count=join->tables;
  if (!(join->join_tab=join_tab=
4811
	(JOIN_TAB*) thd->alloc(sizeof(JOIN_TAB)*table_count)))
unknown's avatar
unknown committed
4812
    DBUG_RETURN(TRUE);
unknown's avatar
unknown committed
4813 4814 4815

  join->full_join=0;

unknown's avatar
unknown committed
4816
  used_tables= OUTER_REF_TABLE_BIT;		// Outer row is already read
unknown's avatar
unknown committed
4817 4818 4819 4820 4821 4822 4823
  for (j=join_tab, tablenr=0 ; tablenr < table_count ; tablenr++,j++)
  {
    TABLE *form;
    *j= *join->best_positions[tablenr].table;
    form=join->table[tablenr]=j->table;
    used_tables|= form->map;
    form->reginfo.join_tab=j;
unknown's avatar
unknown committed
4824
    if (!*j->on_expr_ref)
unknown's avatar
unknown committed
4825
      form->reginfo.not_exists_optimize=0;	// Only with LEFT JOIN
unknown's avatar
unknown committed
4826
    DBUG_PRINT("info",("type: %d", j->type));
4827 4828 4829 4830 4831
    if (j->type == JT_CONST)
      continue;					// Handled in make_join_stat..

    j->ref.key = -1;
    j->ref.key_parts=0;
unknown's avatar
unknown committed
4832 4833 4834

    if (j->type == JT_SYSTEM)
      continue;
4835
    if (j->keys.is_clear_all() || !(keyuse= join->best_positions[tablenr].key))
unknown's avatar
unknown committed
4836 4837 4838 4839 4840
    {
      j->type=JT_ALL;
      if (tablenr != join->const_tables)
	join->full_join=1;
    }
4841
    else if (create_ref_for_key(join, j, keyuse, used_tables))
unknown's avatar
unknown committed
4842
      DBUG_RETURN(TRUE);                        // Something went wrong
4843
  }
unknown's avatar
unknown committed
4844

4845 4846 4847
  for (i=0 ; i < table_count ; i++)
    join->map2table[join->join_tab[i].table->tablenr]=join->join_tab+i;
  update_depend_map(join);
unknown's avatar
unknown committed
4848
  DBUG_RETURN(0);
4849
}
4850

unknown's avatar
unknown committed
4851

4852 4853 4854 4855 4856 4857 4858 4859 4860
static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, KEYUSE *org_keyuse,
			       table_map used_tables)
{
  KEYUSE *keyuse=org_keyuse;
  bool ftkey=(keyuse->keypart == FT_KEYPART);
  THD  *thd= join->thd;
  uint keyparts,length,key;
  TABLE *table;
  KEY *keyinfo;
unknown's avatar
unknown committed
4861
  DBUG_ENTER("create_ref_for_key");
4862

4863
  /*  Use best key from find_best */
4864 4865 4866 4867 4868 4869 4870 4871 4872 4873 4874 4875 4876 4877 4878
  table=j->table;
  key=keyuse->key;
  keyinfo=table->key_info+key;

  if (ftkey)
  {
    Item_func_match *ifm=(Item_func_match *)keyuse->val;

    length=0;
    keyparts=1;
    ifm->join_key=1;
  }
  else
  {
    keyparts=length=0;
4879 4880 4881 4882 4883 4884
    uint found_part_ref_or_null= 0;
    /*
      Calculate length for the used key
      Stop if there is a missing key part or when we find second key_part
      with KEY_OPTIMIZE_REF_OR_NULL
    */
4885 4886
    do
    {
4887
      if (!(~used_tables & keyuse->used_tables))
unknown's avatar
unknown committed
4888
      {
4889 4890
	if (keyparts == keyuse->keypart &&
	    !(found_part_ref_or_null & keyuse->optimize))
unknown's avatar
unknown committed
4891
	{
4892
	  keyparts++;
4893 4894
	  length+= keyinfo->key_part[keyuse->keypart].store_length;
	  found_part_ref_or_null|= keyuse->optimize;
unknown's avatar
unknown committed
4895 4896
	}
      }
4897 4898 4899 4900 4901 4902 4903 4904 4905 4906 4907 4908 4909 4910
      keyuse++;
    } while (keyuse->table == table && keyuse->key == key);
  } /* not ftkey */

  /* set up fieldref */
  keyinfo=table->key_info+key;
  j->ref.key_parts=keyparts;
  j->ref.key_length=length;
  j->ref.key=(int) key;
  if (!(j->ref.key_buff= (byte*) thd->calloc(ALIGN_SIZE(length)*2)) ||
      !(j->ref.key_copy= (store_key**) thd->alloc((sizeof(store_key*) *
						   (keyparts+1)))) ||
      !(j->ref.items=    (Item**) thd->alloc(sizeof(Item*)*keyparts)))
  {
unknown's avatar
unknown committed
4911
    DBUG_RETURN(TRUE);
4912 4913 4914
  }
  j->ref.key_buff2=j->ref.key_buff+ALIGN_SIZE(length);
  j->ref.key_err=1;
4915
  j->ref.null_rejecting= 0;
4916 4917
  keyuse=org_keyuse;

4918 4919
  store_key **ref_key= j->ref.key_copy;
  byte *key_buff=j->ref.key_buff, *null_ref_key= 0;
4920
  bool keyuse_uses_no_tables= TRUE;
4921 4922 4923 4924
  if (ftkey)
  {
    j->ref.items[0]=((Item_func*)(keyuse->val))->key_item();
    if (keyuse->used_tables)
unknown's avatar
unknown committed
4925
      DBUG_RETURN(TRUE);                        // not supported yet. SerG
4926 4927 4928 4929 4930 4931 4932 4933 4934 4935 4936 4937 4938 4939

    j->type=JT_FT;
  }
  else
  {
    uint i;
    for (i=0 ; i < keyparts ; keyuse++,i++)
    {
      while (keyuse->keypart != i ||
	     ((~used_tables) & keyuse->used_tables))
	keyuse++;				/* Skip other parts */

      uint maybe_null= test(keyinfo->key_part[i].null_bit);
      j->ref.items[i]=keyuse->val;		// Save for cond removal
4940 4941
      if (keyuse->null_rejecting) 
        j->ref.null_rejecting |= 1 << i;
4942
      keyuse_uses_no_tables= keyuse_uses_no_tables && !keyuse->used_tables;
4943 4944 4945
      if (!keyuse->used_tables &&
	  !(join->select_options & SELECT_DESCRIBE))
      {					// Compare against constant
unknown's avatar
unknown committed
4946 4947 4948 4949
	store_key_item tmp(thd, keyinfo->key_part[i].field,
                           (char*)key_buff + maybe_null,
                           maybe_null ?  (char*) key_buff : 0,
                           keyinfo->key_part[i].length, keyuse->val);
4950
	if (thd->is_fatal_error)
unknown's avatar
unknown committed
4951
	  DBUG_RETURN(TRUE);
unknown's avatar
unknown committed
4952
	tmp.copy();
unknown's avatar
unknown committed
4953 4954
      }
      else
4955 4956 4957 4958
	*ref_key++= get_store_key(thd,
				  keyuse,join->const_table_map,
				  &keyinfo->key_part[i],
				  (char*) key_buff,maybe_null);
unknown's avatar
af  
unknown committed
4959
      /*
4960
	Remember if we are going to use REF_OR_NULL
unknown's avatar
af  
unknown committed
4961 4962 4963 4964
	But only if field _really_ can be null i.e. we force JT_REF
	instead of JT_REF_OR_NULL in case if field can't be null
      */
      if ((keyuse->optimize & KEY_OPTIMIZE_REF_OR_NULL) && maybe_null)
4965
	null_ref_key= key_buff;
4966
      key_buff+=keyinfo->key_part[i].store_length;
unknown's avatar
unknown committed
4967
    }
4968 4969
  } /* not ftkey */
  *ref_key=0;				// end_marker
4970
  if (j->type == JT_FT)
unknown's avatar
unknown committed
4971
    DBUG_RETURN(0);
4972 4973
  if (j->type == JT_CONST)
    j->table->const_table= 1;
4974
  else if (((keyinfo->flags & (HA_NOSAME | HA_NULL_PART_KEY |
unknown's avatar
unknown committed
4975
			       HA_END_SPACE_KEY)) != HA_NOSAME) ||
unknown's avatar
unknown committed
4976
	   keyparts != keyinfo->key_parts || null_ref_key)
4977 4978 4979
  {
    /* Must read with repeat */
    j->type= null_ref_key ? JT_REF_OR_NULL : JT_REF;
unknown's avatar
af  
unknown committed
4980
    j->ref.null_ref_key= null_ref_key;
4981
  }
4982
  else if (keyuse_uses_no_tables)
4983
  {
4984 4985 4986 4987 4988 4989 4990 4991
    /*
      This happen if we are using a constant expression in the ON part
      of an LEFT JOIN.
      SELECT * FROM a LEFT JOIN b ON b.key=30
      Here we should not mark the table as a 'const' as a field may
      have a 'normal' value or a NULL value.
    */
    j->type=JT_CONST;
unknown's avatar
unknown committed
4992
  }
4993 4994
  else
    j->type=JT_EQ_REF;
unknown's avatar
unknown committed
4995
  DBUG_RETURN(0);
unknown's avatar
unknown committed
4996 4997 4998
}


4999

unknown's avatar
unknown committed
5000
static store_key *
unknown's avatar
unknown committed
5001 5002
get_store_key(THD *thd, KEYUSE *keyuse, table_map used_tables,
	      KEY_PART_INFO *key_part, char *key_buff, uint maybe_null)
unknown's avatar
unknown committed
5003 5004 5005
{
  if (!((~used_tables) & keyuse->used_tables))		// if const item
  {
unknown's avatar
unknown committed
5006 5007
    return new store_key_const_item(thd,
				    key_part->field,
unknown's avatar
unknown committed
5008 5009 5010 5011 5012 5013
				    key_buff + maybe_null,
				    maybe_null ? key_buff : 0,
				    key_part->length,
				    keyuse->val);
  }
  else if (keyuse->val->type() == Item::FIELD_ITEM)
unknown's avatar
unknown committed
5014 5015
    return new store_key_field(thd,
			       key_part->field,
unknown's avatar
unknown committed
5016 5017 5018 5019 5020
			       key_buff + maybe_null,
			       maybe_null ? key_buff : 0,
			       key_part->length,
			       ((Item_field*) keyuse->val)->field,
			       keyuse->val->full_name());
unknown's avatar
unknown committed
5021 5022
  return new store_key_item(thd,
			    key_part->field,
unknown's avatar
unknown committed
5023 5024 5025 5026 5027 5028 5029
			    key_buff + maybe_null,
			    maybe_null ? key_buff : 0,
			    key_part->length,
			    keyuse->val);
}

/*
5030 5031
  This function is only called for const items on fields which are keys
  returns 1 if there was some conversion made when the field was stored.
unknown's avatar
unknown committed
5032 5033 5034 5035 5036
*/

bool
store_val_in_field(Field *field,Item *item)
{
5037
  bool error;
unknown's avatar
unknown committed
5038
  THD *thd= field->table->in_use;
5039
  ha_rows cuted_fields=thd->cuted_fields;
unknown's avatar
af  
unknown committed
5040 5041 5042 5043 5044 5045
  /*
    we should restore old value of count_cuted_fields because
    store_val_in_field can be called from mysql_insert 
    with select_insert, which make count_cuted_fields= 1
   */
  enum_check_fields old_count_cuted_fields= thd->count_cuted_fields;
5046
  thd->count_cuted_fields= CHECK_FIELD_WARN;
5047
  error= item->save_in_field(field, 1);
unknown's avatar
af  
unknown committed
5048
  thd->count_cuted_fields= old_count_cuted_fields;
5049
  return error || cuted_fields != thd->cuted_fields;
unknown's avatar
unknown committed
5050 5051 5052 5053 5054 5055 5056 5057
}


static bool
make_simple_join(JOIN *join,TABLE *tmp_table)
{
  TABLE **tableptr;
  JOIN_TAB *join_tab;
unknown's avatar
unknown committed
5058
  DBUG_ENTER("make_simple_join");
unknown's avatar
unknown committed
5059

5060 5061
  if (!(tableptr=(TABLE**) join->thd->alloc(sizeof(TABLE*))) ||
      !(join_tab=(JOIN_TAB*) join->thd->alloc(sizeof(JOIN_TAB))))
unknown's avatar
unknown committed
5062
    DBUG_RETURN(TRUE);
unknown's avatar
unknown committed
5063 5064 5065 5066 5067
  join->join_tab=join_tab;
  join->table=tableptr; tableptr[0]=tmp_table;
  join->tables=1;
  join->const_tables=0;
  join->const_table_map=0;
unknown's avatar
unknown committed
5068 5069 5070
  join->tmp_table_param.field_count= join->tmp_table_param.sum_func_count=
    join->tmp_table_param.func_count=0;
  join->tmp_table_param.copy_field=join->tmp_table_param.copy_field_end=0;
unknown's avatar
unknown committed
5071
  join->first_record=join->sort_and_group=0;
unknown's avatar
unknown committed
5072
  join->send_records=(ha_rows) 0;
unknown's avatar
unknown committed
5073
  join->group=0;
unknown's avatar
unknown committed
5074
  join->row_limit=join->unit->select_limit_cnt;
unknown's avatar
unknown committed
5075
  join->do_send_rows = (join->row_limit) ? 1 : 0;
unknown's avatar
unknown committed
5076

unknown's avatar
unknown committed
5077
  join_tab->cache.buff=0;			/* No caching */
unknown's avatar
unknown committed
5078 5079 5080 5081 5082
  join_tab->table=tmp_table;
  join_tab->select=0;
  join_tab->select_cond=0;
  join_tab->quick=0;
  join_tab->type= JT_ALL;			/* Map through all records */
5083 5084
  join_tab->keys.init();
  join_tab->keys.set_all();                     /* test everything in quick */
unknown's avatar
unknown committed
5085
  join_tab->info=0;
unknown's avatar
unknown committed
5086
  join_tab->on_expr_ref=0;
5087 5088
  join_tab->last_inner= 0;
  join_tab->first_unmatched= 0;
unknown's avatar
unknown committed
5089
  join_tab->ref.key = -1;
unknown's avatar
unknown committed
5090 5091
  join_tab->not_used_in_distinct=0;
  join_tab->read_first_record= join_init_read_record;
5092
  join_tab->join=join;
unknown's avatar
unknown committed
5093
  join_tab->ref.key_parts= 0;
unknown's avatar
unknown committed
5094
  bzero((char*) &join_tab->read_record,sizeof(join_tab->read_record));
unknown's avatar
unknown committed
5095 5096
  tmp_table->status=0;
  tmp_table->null_row=0;
unknown's avatar
unknown committed
5097
  DBUG_RETURN(FALSE);
unknown's avatar
unknown committed
5098 5099 5100
}


5101 5102 5103 5104 5105 5106 5107 5108 5109 5110 5111 5112 5113 5114 5115 5116 5117 5118 5119 5120 5121 5122 5123 5124 5125 5126 5127 5128 5129 5130 5131 5132 5133 5134 5135 5136 5137 5138 5139 5140 5141 5142 5143 5144 5145 5146 5147 5148 5149 5150 5151 5152 5153 5154 5155 5156 5157 5158 5159 5160 5161 5162 5163 5164 5165 5166 5167 5168 5169 5170
inline void add_cond_and_fix(Item **e1, Item *e2)
{
  if (*e1)
  {
    Item *res;
    if ((res= new Item_cond_and(*e1, e2)))
    {
      *e1= res;
      res->quick_fix_field();
    }
  }
  else
    *e1= e2;
}


/*
  Add to join_tab->select_cond[i] "table.field IS NOT NULL" conditions we've
  inferred from ref/eq_ref access performed.

  SYNOPSIS
    add_not_null_conds()
      join  Join to process

  NOTES
    This function is a part of "Early NULL-values filtering for ref access"
    optimization.

    Example of this optimization:
      For query SELECT * FROM t1,t2 WHERE t2.key=t1.field
      and plan " any-access(t1), ref(t2.key=t1.field) "
      add "t1.field IS NOT NULL" to t1's table condition.
    Description of the optimization:
    
      We look through equalities choosen to perform ref/eq_ref access,
      pick equalities that have form "tbl.part_of_key = othertbl.field"
      (where othertbl is a non-const table and othertbl.field may be NULL)
      and add them to conditions on correspoding tables (othertbl in this
      example).
      
      This optimization doesn't affect the choices that ref, range, or join
      optimizer make. This was intentional because this was added after 4.1
      was GA.
      
    Implementation overview
      1. update_ref_and_keys() accumulates info about null-rejecting
         predicates in in KEY_FIELD::null_rejecting
      1.1 add_key_part saves these to KEYUSE.
      2. create_ref_for_key copies them to TABLE_REF.
      3. add_not_null_conds adds "x IS NOT NULL" to join_tab->select_cond of
         appropiate JOIN_TAB members.
*/

static void add_not_null_conds(JOIN *join)
{
  DBUG_ENTER("add_not_null_conds");
  for (uint i=join->const_tables ; i < join->tables ; i++)
  {
    JOIN_TAB *tab=join->join_tab+i;
    if ((tab->type == JT_REF || tab->type == JT_REF_OR_NULL) &&
         !tab->table->maybe_null)
    {
      for (uint keypart= 0; keypart < tab->ref.key_parts; keypart++)
      {
        if (tab->ref.null_rejecting & (1 << keypart))
        {
          Item *item= tab->ref.items[keypart];
          DBUG_ASSERT(item->type() == Item::FIELD_ITEM);
          Item_field *not_null_item= (Item_field*)item;
          JOIN_TAB *referred_tab= not_null_item->field->table->reginfo.join_tab;
5171 5172
          Item_func_isnotnull *notnull;
          if (!(notnull= new Item_func_isnotnull(not_null_item)))
5173 5174
            DBUG_VOID_RETURN;

5175 5176
          notnull->quick_fix_field();
          DBUG_EXECUTE("where",print_where(notnull,
unknown's avatar
unknown committed
5177
                                           referred_tab->table->alias););
5178
          add_cond_and_fix(&referred_tab->select_cond, notnull);
5179 5180 5181 5182 5183 5184 5185
        }
      }
    }
  }
  DBUG_VOID_RETURN;
}

5186 5187 5188 5189 5190 5191 5192 5193 5194 5195 5196 5197 5198 5199 5200 5201 5202 5203 5204 5205 5206 5207 5208 5209 5210 5211 5212 5213 5214 5215
/*
  Build a predicate guarded by match variables for embedding outer joins

  SYNOPSIS
    add_found_match_trig_cond()
    tab       the first inner table for most nested outer join
    cond      the predicate to be guarded
    root_tab  the first inner table to stop

  DESCRIPTION
    The function recursively adds guards for predicate cond
    assending from tab to the first inner table  next embedding
    nested outer join and so on until it reaches root_tab
    (root_tab can be 0).

  RETURN VALUE
    pointer to the guarded predicate, if success
    0, otherwise
*/ 

static COND*
add_found_match_trig_cond(JOIN_TAB *tab, COND *cond, JOIN_TAB *root_tab)
{
  COND *tmp;
  if (tab == root_tab || !cond)
    return cond;
  if ((tmp= add_found_match_trig_cond(tab->first_upper, cond, root_tab)))
  {
    tmp= new Item_func_trig_cond(tmp, &tab->found);
  }
unknown's avatar
unknown committed
5216
  if (tmp)
5217
  {
unknown's avatar
unknown committed
5218
    tmp->quick_fix_field();
5219 5220
    tmp->update_used_tables();
  }
5221 5222 5223 5224 5225 5226 5227 5228 5229 5230 5231 5232 5233 5234 5235 5236 5237 5238 5239 5240 5241 5242 5243
  return tmp;
}


/*
   Fill in outer join related info for the execution plan structure

  SYNOPSIS
    make_outerjoin_info()
    join - reference to the info fully describing the query

  DESCRIPTION
    For each outer join operation left after simplification of the
    original query the function set up the following pointers in the linear
    structure join->join_tab representing the selected execution plan.
    The first inner table t0 for the operation is set to refer to the last
    inner table tk through the field t0->last_inner.
    Any inner table ti for the operation are set to refer to the first
    inner table ti->first_inner.
    The first inner table t0 for the operation is set to refer to the
    first inner table of the embedding outer join operation, if there is any,
    through the field t0->first_upper.
    The on expression for the outer join operation is attached to the
unknown's avatar
unknown committed
5244
    corresponding first inner table through the field t0->on_expr_ref.
5245 5246 5247
    Here ti are structures of the JOIN_TAB type.

  EXAMPLE
unknown's avatar
unknown committed
5248
    For the query: 
5249 5250 5251 5252 5253 5254 5255 5256 5257
      SELECT * FROM t1
                    LEFT JOIN
                    (t2, t3 LEFT JOIN t4 ON t3.a=t4.a)
                    ON (t1.a=t2.a AND t1.b=t3.b)
        WHERE t1.c > 5,
    given the execution plan with the table order t1,t2,t3,t4
    is selected, the following references will be set;
    t4->last_inner=[t4], t4->first_inner=[t4], t4->first_upper=[t2]
    t2->last_inner=[t4], t2->first_inner=t3->first_inner=[t2],
unknown's avatar
unknown committed
5258 5259
    on expression (t1.a=t2.a AND t1.b=t3.b) will be attached to 
    *t2->on_expr_ref, while t3.a=t4.a will be attached to *t4->on_expr_ref.
5260 5261 5262 5263 5264 5265 5266 5267 5268 5269 5270
            
  NOTES
    The function assumes that the simplification procedure has been
    already applied to the join query (see simplify_joins).
    This function can be called only after the execution plan
    has been chosen.
*/
 
static void
make_outerjoin_info(JOIN *join)
{
5271
  DBUG_ENTER("make_outerjoin_info");
5272 5273 5274 5275 5276 5277 5278 5279 5280 5281 5282 5283 5284 5285 5286
  for (uint i=join->const_tables ; i < join->tables ; i++)
  {
    JOIN_TAB *tab=join->join_tab+i;
    TABLE *table=tab->table;
    TABLE_LIST *tbl= table->pos_in_table_list;
    TABLE_LIST *embedding= tbl->embedding;

    if (tbl->outer_join)
    {
      /* 
        Table tab is the only one inner table for outer join.
        (Like table t4 for the table reference t3 LEFT JOIN t4 ON t3.a=t4.a
        is in the query above.)
      */
      tab->last_inner= tab->first_inner= tab;
unknown's avatar
unknown committed
5287 5288
      tab->on_expr_ref= &tbl->on_expr;
      tab->cond_equal= tbl->cond_equal;
5289 5290 5291
      if (embedding)
        tab->first_upper= embedding->nested_join->first_nested;
    }    
unknown's avatar
unknown committed
5292
    for ( ; embedding ; embedding= embedding->embedding)
5293 5294 5295 5296 5297 5298 5299 5300 5301
    {
      NESTED_JOIN *nested_join= embedding->nested_join;
      if (!nested_join->counter)
      {
        /* 
          Table tab is the first inner table for nested_join.
          Save reference to it in the nested join structure.
        */ 
        nested_join->first_nested= tab;
unknown's avatar
unknown committed
5302 5303
        tab->on_expr_ref= &embedding->on_expr;
        tab->cond_equal= tbl->cond_equal;
5304 5305 5306 5307 5308 5309 5310 5311 5312 5313 5314
        if (embedding->embedding)
          tab->first_upper= embedding->embedding->nested_join->first_nested;
      }
      if (!tab->first_inner)  
        tab->first_inner= nested_join->first_nested;
      if (++nested_join->counter < nested_join->join_list.elements)
        break;
      /* Table tab is the last inner table for nested join. */
      nested_join->first_nested->last_inner= tab;
    }
  }
5315
  DBUG_VOID_RETURN;
5316 5317 5318
}


unknown's avatar
unknown committed
5319 5320 5321
static bool
make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
{
unknown's avatar
unknown committed
5322
  THD *thd= join->thd;
unknown's avatar
unknown committed
5323 5324 5325
  DBUG_ENTER("make_join_select");
  if (select)
  {
5326
    add_not_null_conds(join);
unknown's avatar
unknown committed
5327
    table_map used_tables;
5328
    if (cond)                /* Because of QUICK_GROUP_MIN_MAX_SELECT */
unknown's avatar
unknown committed
5329
    {                        /* there may be a select without a cond. */    
5330 5331 5332
      if (join->tables > 1)
        cond->update_used_tables();		// Tablenr may have changed
      if (join->const_tables == join->tables &&
unknown's avatar
unknown committed
5333 5334
	  thd->lex->current_select->master_unit() ==
	  &thd->lex->unit)		// not upper level SELECT
5335 5336 5337
        join->const_table_map|=RAND_TABLE_BIT;
      {						// Check const tables
        COND *const_cond=
5338
	  make_cond_for_table(cond,join->const_table_map,(table_map) 0);
5339
        DBUG_EXECUTE("where",print_where(const_cond,"constants"););
5340 5341 5342
        for (JOIN_TAB *tab= join->join_tab+join->const_tables;
             tab < join->join_tab+join->tables ; tab++)
        {
5343
          if (*tab->on_expr_ref)
5344 5345
          {
            JOIN_TAB *cond_tab= tab->first_inner;
5346
            COND *tmp= make_cond_for_table(*tab->on_expr_ref,
5347
                                           join->const_table_map,
5348
                                         (  table_map) 0);
5349 5350 5351 5352 5353 5354 5355
            if (!tmp)
              continue;
            tmp= new Item_func_trig_cond(tmp, &cond_tab->not_null_compl);
            if (!tmp)
              DBUG_RETURN(1);
            tmp->quick_fix_field();
            cond_tab->select_cond= !cond_tab->select_cond ? tmp :
5356
	                            new Item_cond_and(cond_tab->select_cond,tmp);
5357
            if (!cond_tab->select_cond)
5358
	      DBUG_RETURN(1);
5359
            cond_tab->select_cond->quick_fix_field();
5360
          }       
5361
        }
5362 5363
        if (const_cond && !const_cond->val_int())
        {
5364
	  DBUG_PRINT("info",("Found impossible WHERE condition"));
unknown's avatar
unknown committed
5365
	  DBUG_RETURN(1);	 // Impossible const condition
5366
        }
5367
      }
unknown's avatar
unknown committed
5368
    }
unknown's avatar
unknown committed
5369 5370
    used_tables=((select->const_tables=join->const_table_map) |
		 OUTER_REF_TABLE_BIT | RAND_TABLE_BIT);
unknown's avatar
unknown committed
5371 5372 5373
    for (uint i=join->const_tables ; i < join->tables ; i++)
    {
      JOIN_TAB *tab=join->join_tab+i;
5374
      JOIN_TAB *first_inner_tab= tab->first_inner; 
unknown's avatar
unknown committed
5375
      table_map current_map= tab->table->map;
5376
      bool use_quick_range=0;
unknown's avatar
unknown committed
5377 5378
      COND *tmp;

unknown's avatar
unknown committed
5379 5380 5381 5382
      /*
	Following force including random expression in last table condition.
	It solve problem with select like SELECT * FROM t1 WHERE rand() > 0.5
      */
5383
      if (i == join->tables-1)
unknown's avatar
unknown committed
5384
	current_map|= OUTER_REF_TABLE_BIT | RAND_TABLE_BIT;
unknown's avatar
unknown committed
5385
      used_tables|=current_map;
5386 5387

      if (tab->type == JT_REF && tab->quick &&
unknown's avatar
unknown committed
5388
	  (uint) tab->ref.key == tab->quick->index &&
5389 5390 5391 5392 5393 5394
	  tab->ref.key_length < tab->quick->max_used_key_length)
      {
	/* Range uses longer key;  Use this instead of ref on key */
	tab->type=JT_ALL;
	use_quick_range=1;
	tab->use_quick=1;
unknown's avatar
af  
unknown committed
5395
        tab->ref.key= -1;
5396
	tab->ref.key_parts=0;		// Don't use ref key.
5397
	join->best_positions[i].records_read= rows2double(tab->quick->records);
5398 5399
      }

unknown's avatar
unknown committed
5400
      tmp= NULL;
5401 5402 5403
      if (cond)
        tmp= make_cond_for_table(cond,used_tables,current_map);
      if (cond && !tmp && tab->quick)
5404
      {						// Outer join
5405 5406 5407 5408 5409 5410 5411 5412 5413 5414 5415 5416 5417 5418 5419 5420 5421
        if (tab->type != JT_ALL)
        {
          /*
            Don't use the quick method
            We come here in the case where we have 'key=constant' and
            the test is removed by make_cond_for_table()
          */
          delete tab->quick;
          tab->quick= 0;
        }
        else
        {
          /*
            Hack to handle the case where we only refer to a table
            in the ON part of an OUTER JOIN. In this case we want the code
            below to check if we should use 'quick' instead.
          */
5422
          DBUG_PRINT("info", ("Item_int"));
5423
          tmp= new Item_int((longlong) 1,1);	// Always true
5424
          DBUG_PRINT("info", ("Item_int 0x%lx", (ulong)tmp));
5425 5426
        }

5427
      }
5428
      if (tmp || !cond)
unknown's avatar
unknown committed
5429
      {
5430
	DBUG_EXECUTE("where",print_where(tmp,tab->table->alias););
unknown's avatar
unknown committed
5431
	SQL_SELECT *sel=tab->select=(SQL_SELECT*)
unknown's avatar
unknown committed
5432
	  thd->memdup((gptr) select, sizeof(SQL_SELECT));
unknown's avatar
unknown committed
5433 5434
	if (!sel)
	  DBUG_RETURN(1);			// End of memory
5435 5436 5437 5438 5439
        /*
          If tab is an inner table of an outer join operation,
          add a match guard to the pushed down predicate.
          The guard will turn the predicate on only after
          the first match for outer tables is encountered.
5440
	*/        
5441
        if (cond)
unknown's avatar
unknown committed
5442 5443
        {
          /*
5444 5445 5446 5447 5448 5449
            Because of QUICK_GROUP_MIN_MAX_SELECT there may be a select without
            a cond, so neutralize the hack above.
          */
          if (!(tmp= add_found_match_trig_cond(first_inner_tab, tmp, 0)))
            DBUG_RETURN(1);
          tab->select_cond=sel->cond=tmp;
5450 5451
          /* Push condition to storage engine if this is enabled
             and the condition is not guarded */
5452
          tab->table->file->pushed_cond= NULL;
5453
	  if (thd->variables.engine_condition_pushdown)
5454
          {
unknown's avatar
unknown committed
5455
            COND *push_cond= 
5456
              make_cond_for_table(tmp, current_map, current_map);
5457 5458 5459 5460 5461 5462
            if (push_cond)
            {
              /* Push condition to handler */
              if (!tab->table->file->cond_push(push_cond))
                tab->table->file->pushed_cond= push_cond;
            }
5463
          }
5464 5465 5466
        }
        else
          tab->select_cond= sel->cond= NULL;
5467

unknown's avatar
unknown committed
5468
	sel->head=tab->table;
unknown's avatar
unknown committed
5469
	DBUG_EXECUTE("where",print_where(tmp,tab->table->alias););
unknown's avatar
unknown committed
5470 5471
	if (tab->quick)
	{
5472 5473
	  /* Use quick key read if it's a constant and it's not used
	     with key reading */
5474
	  if (tab->needed_reg.is_clear_all() && tab->type != JT_EQ_REF
5475
	      && tab->type != JT_FT && (tab->type != JT_REF ||
unknown's avatar
unknown committed
5476
               (uint) tab->ref.key == tab->quick->index))
unknown's avatar
unknown committed
5477 5478
	  {
	    sel->quick=tab->quick;		// Use value from get_quick_...
5479 5480
	    sel->quick_keys.clear_all();
	    sel->needed_reg.clear_all();
unknown's avatar
unknown committed
5481 5482 5483 5484 5485 5486 5487 5488 5489 5490
	  }
	  else
	  {
	    delete tab->quick;
	  }
	  tab->quick=0;
	}
	uint ref_key=(uint) sel->head->reginfo.join_tab->ref.key+1;
	if (i == join->const_tables && ref_key)
	{
5491 5492
	  if (!tab->const_keys.is_clear_all() &&
              tab->table->reginfo.impossible_range)
unknown's avatar
unknown committed
5493 5494
	    DBUG_RETURN(1);
	}
5495
	else if (tab->type == JT_ALL && ! use_quick_range)
unknown's avatar
unknown committed
5496
	{
5497
	  if (!tab->const_keys.is_clear_all() &&
unknown's avatar
unknown committed
5498 5499 5500 5501
	      tab->table->reginfo.impossible_range)
	    DBUG_RETURN(1);				// Impossible range
	  /*
	    We plan to scan all rows.
5502 5503 5504
	    Check again if we should use an index.
	    We could have used an column from a previous table in
	    the index if we are using limit and this is the first table
unknown's avatar
unknown committed
5505 5506
	  */

5507 5508
	  if (cond &&
              (!tab->keys.is_subset(tab->const_keys) && i > 0) ||
5509 5510
	      (!tab->const_keys.is_clear_all() && i == join->const_tables &&
	       join->unit->select_limit_cnt <
5511
	       join->best_positions[i].records_read &&
5512
	       !(join->select_options & OPTION_FOUND_ROWS)))
unknown's avatar
unknown committed
5513
	  {
5514 5515
	    /* Join with outer join condition */
	    COND *orig_cond=sel->cond;
unknown's avatar
unknown committed
5516
	    sel->cond= and_conds(sel->cond, *tab->on_expr_ref);
5517 5518 5519 5520 5521 5522 5523 5524

	    /*
              We can't call sel->cond->fix_fields,
              as it will break tab->on_expr if it's AND condition
              (fix_fields currently removes extra AND/OR levels).
              Yet attributes of the just built condition are not needed.
              Thus we call sel->cond->quick_fix_field for safety.
	    */
unknown's avatar
af  
unknown committed
5525
	    if (sel->cond && !sel->cond->fixed)
5526 5527
	      sel->cond->quick_fix_field();

unknown's avatar
unknown committed
5528
	    if (sel->test_quick_select(thd, tab->keys,
unknown's avatar
unknown committed
5529
				       used_tables & ~ current_map,
5530 5531 5532
				       (join->select_options &
					OPTION_FOUND_ROWS ?
					HA_POS_ERROR :
5533
					join->unit->select_limit_cnt), 0) < 0)
unknown's avatar
unknown committed
5534 5535 5536 5537 5538
            {
	      /*
		Before reporting "Impossible WHERE" for the whole query
		we have to check isn't it only "impossible ON" instead
	      */
5539
              sel->cond=orig_cond;
unknown's avatar
unknown committed
5540
              if (!*tab->on_expr_ref ||
unknown's avatar
unknown committed
5541
                  sel->test_quick_select(thd, tab->keys,
5542 5543 5544 5545
                                         used_tables & ~ current_map,
                                         (join->select_options &
                                          OPTION_FOUND_ROWS ?
                                          HA_POS_ERROR :
5546
                                          join->unit->select_limit_cnt),0) < 0)
unknown's avatar
unknown committed
5547
		DBUG_RETURN(1);			// Impossible WHERE
5548 5549 5550 5551
            }
            else
	      sel->cond=orig_cond;

5552 5553 5554
	    /* Fix for EXPLAIN */
	    if (sel->quick)
	      join->best_positions[i].records_read= sel->quick->records;
unknown's avatar
unknown committed
5555 5556 5557 5558
	  }
	  else
	  {
	    sel->needed_reg=tab->needed_reg;
5559
	    sel->quick_keys.clear_all();
unknown's avatar
unknown committed
5560
	  }
5561 5562
	  if (!sel->quick_keys.is_subset(tab->checked_keys) ||
              !sel->needed_reg.is_subset(tab->checked_keys))
unknown's avatar
unknown committed
5563
	  {
5564 5565 5566 5567
	    tab->keys=sel->quick_keys;
            tab->keys.merge(sel->needed_reg);
	    tab->use_quick= (!sel->needed_reg.is_clear_all() &&
			     (select->quick_keys.is_clear_all() ||
unknown's avatar
unknown committed
5568 5569 5570
			      (select->quick &&
			       (select->quick->records >= 100L)))) ?
	      2 : 1;
unknown's avatar
unknown committed
5571
	    sel->read_tables= used_tables & ~current_map;
unknown's avatar
unknown committed
5572 5573 5574
	  }
	  if (i != join->const_tables && tab->use_quick != 2)
	  {					/* Read with cache */
5575 5576
	    if (cond &&
                (tmp=make_cond_for_table(cond,
unknown's avatar
unknown committed
5577 5578 5579 5580 5581
					 join->const_table_map |
					 current_map,
					 current_map)))
	    {
	      DBUG_EXECUTE("where",print_where(tmp,"cache"););
5582
	      tab->cache.select=(SQL_SELECT*)
unknown's avatar
unknown committed
5583
		thd->memdup((gptr) sel, sizeof(SQL_SELECT));
unknown's avatar
unknown committed
5584 5585 5586 5587 5588
	      tab->cache.select->cond=tmp;
	      tab->cache.select->read_tables=join->const_table_map;
	    }
	  }
	}
unknown's avatar
unknown committed
5589
      }
5590 5591 5592 5593 5594 5595 5596 5597 5598 5599 5600 5601 5602 5603 5604 5605
      
      /* 
        Push down all predicates from on expressions.
        Each of these predicated are guarded by a variable
        that turns if off just before null complemented row for
        outer joins is formed. Thus, the predicates from an
        'on expression' are guaranteed not to be checked for
        the null complemented row.
      */ 
      JOIN_TAB *last_tab= tab;
      while (first_inner_tab && first_inner_tab->last_inner == last_tab)
      {  
        /* 
          Table tab is the last inner table of an outer join.
          An on expression is always attached to it.
	*/     
unknown's avatar
unknown committed
5606
        COND *on_expr= *first_inner_tab->on_expr_ref;
5607 5608 5609 5610 5611 5612 5613 5614 5615 5616 5617 5618 5619 5620 5621 5622 5623 5624 5625 5626 5627 5628

        table_map used_tables= join->const_table_map |
		               OUTER_REF_TABLE_BIT | RAND_TABLE_BIT;
	for (tab= join->join_tab+join->const_tables; tab <= last_tab ; tab++)
        {
          current_map= tab->table->map;
          used_tables|= current_map;
          COND *tmp= make_cond_for_table(on_expr, used_tables, current_map);
          if (tmp)
          {
            JOIN_TAB *cond_tab= tab < first_inner_tab ? first_inner_tab : tab;
            /*
              First add the guards for match variables of
              all embedding outer join operations.
	    */
            if (!(tmp= add_found_match_trig_cond(cond_tab->first_inner,
                                                 tmp, first_inner_tab)))
              DBUG_RETURN(1);
            /* 
              Now add the guard turning the predicate off for 
              the null complemented row.
	    */ 
5629
            DBUG_PRINT("info", ("Item_func_trig_cond"));
5630 5631
            tmp= new Item_func_trig_cond(tmp, 
                                         &first_inner_tab->not_null_compl);
5632
            DBUG_PRINT("info", ("Item_func_trig_cond 0x%lx", (ulong) tmp));
unknown's avatar
unknown committed
5633 5634
            if (tmp)
              tmp->quick_fix_field();
5635
	    /* Add the predicate to other pushed down predicates */
5636
            DBUG_PRINT("info", ("Item_cond_and"));
5637 5638
            cond_tab->select_cond= !cond_tab->select_cond ? tmp :
	                          new Item_cond_and(cond_tab->select_cond,tmp);
5639 5640
            DBUG_PRINT("info", ("Item_cond_and 0x%lx",
                                (ulong)cond_tab->select_cond));
5641 5642
            if (!cond_tab->select_cond)
	      DBUG_RETURN(1);
unknown's avatar
unknown committed
5643
            cond_tab->select_cond->quick_fix_field();
5644 5645 5646
          }              
        }
        first_inner_tab= first_inner_tab->first_upper;       
unknown's avatar
unknown committed
5647 5648 5649 5650 5651 5652 5653
      }
    }
  }
  DBUG_RETURN(0);
}

static void
5654
make_join_readinfo(JOIN *join, uint options)
unknown's avatar
unknown committed
5655 5656
{
  uint i;
5657

unknown's avatar
af  
unknown committed
5658
  bool statistics= test(!(join->select_options & SELECT_DESCRIBE));
unknown's avatar
unknown committed
5659 5660 5661 5662 5663 5664 5665 5666 5667 5668 5669 5670 5671 5672 5673 5674 5675 5676 5677
  DBUG_ENTER("make_join_readinfo");

  for (i=join->const_tables ; i < join->tables ; i++)
  {
    JOIN_TAB *tab=join->join_tab+i;
    TABLE *table=tab->table;
    tab->read_record.table= table;
    tab->read_record.file=table->file;
    tab->next_select=sub_select;		/* normal select */
    switch (tab->type) {
    case JT_SYSTEM:				// Only happens with left join
      table->status=STATUS_NO_RECORD;
      tab->read_first_record= join_read_system;
      tab->read_record.read_record= join_no_more_records;
      break;
    case JT_CONST:				// Only happens with left join
      table->status=STATUS_NO_RECORD;
      tab->read_first_record= join_read_const;
      tab->read_record.read_record= join_no_more_records;
unknown's avatar
af  
unknown committed
5678 5679 5680 5681 5682 5683
      if (table->used_keys.is_set(tab->ref.key) &&
          !table->no_keyread)
      {
        table->key_read=1;
        table->file->extra(HA_EXTRA_KEYREAD);
      }
unknown's avatar
unknown committed
5684 5685 5686
      break;
    case JT_EQ_REF:
      table->status=STATUS_NO_RECORD;
5687 5688 5689 5690 5691
      if (tab->select)
      {
	delete tab->select->quick;
	tab->select->quick=0;
      }
unknown's avatar
unknown committed
5692 5693 5694 5695
      delete tab->quick;
      tab->quick=0;
      tab->read_first_record= join_read_key;
      tab->read_record.read_record= join_no_more_records;
5696
      if (table->used_keys.is_set(tab->ref.key) &&
unknown's avatar
unknown committed
5697
	  !table->no_keyread)
unknown's avatar
unknown committed
5698 5699 5700 5701 5702
      {
	table->key_read=1;
	table->file->extra(HA_EXTRA_KEYREAD);
      }
      break;
5703
    case JT_REF_OR_NULL:
unknown's avatar
unknown committed
5704 5705
    case JT_REF:
      table->status=STATUS_NO_RECORD;
5706 5707 5708 5709 5710
      if (tab->select)
      {
	delete tab->select->quick;
	tab->select->quick=0;
      }
unknown's avatar
unknown committed
5711 5712
      delete tab->quick;
      tab->quick=0;
5713
      if (table->used_keys.is_set(tab->ref.key) &&
unknown's avatar
unknown committed
5714
	  !table->no_keyread)
unknown's avatar
unknown committed
5715 5716 5717 5718
      {
	table->key_read=1;
	table->file->extra(HA_EXTRA_KEYREAD);
      }
5719 5720 5721 5722 5723 5724 5725 5726 5727 5728
      if (tab->type == JT_REF)
      {
	tab->read_first_record= join_read_always_key;
	tab->read_record.read_record= join_read_next_same;
      }
      else
      {
	tab->read_first_record= join_read_always_key_or_null;
	tab->read_record.read_record= join_read_next_same_or_null;
      }
unknown's avatar
unknown committed
5729 5730 5731 5732 5733 5734 5735 5736
      break;
    case JT_FT:
      table->status=STATUS_NO_RECORD;
      tab->read_first_record= join_ft_read_first;
      tab->read_record.read_record= join_ft_read_next;
      break;
    case JT_ALL:
      /*
5737
	If previous table use cache
unknown's avatar
unknown committed
5738 5739
      */
      table->status=STATUS_NO_RECORD;
unknown's avatar
unknown committed
5740
      if (i != join->const_tables && !(options & SELECT_NO_JOIN_CACHE) &&
5741
          tab->use_quick != 2 && !tab->first_inner)
unknown's avatar
unknown committed
5742 5743 5744 5745 5746 5747 5748 5749 5750 5751
      {
	if ((options & SELECT_DESCRIBE) ||
	    !join_init_cache(join->thd,join->join_tab+join->const_tables,
			     i-join->const_tables))
	{
	  tab[-1].next_select=sub_select_cache; /* Patch previous */
	}
      }
      /* These init changes read_record */
      if (tab->use_quick == 2)
5752
      {
5753
	join->thd->server_status|=SERVER_QUERY_NO_GOOD_INDEX_USED;
unknown's avatar
unknown committed
5754
	tab->read_first_record= join_init_quick_read_record;
unknown's avatar
af  
unknown committed
5755
	if (statistics)
5756 5757
	  statistic_increment(join->thd->status_var.select_range_check_count,
			      &LOCK_status);
5758
      }
unknown's avatar
unknown committed
5759 5760 5761
      else
      {
	tab->read_first_record= join_init_read_record;
5762 5763 5764 5765
	if (i == join->const_tables)
	{
	  if (tab->select && tab->select->quick)
	  {
unknown's avatar
af  
unknown committed
5766
	    if (statistics)
5767 5768
	      statistic_increment(join->thd->status_var.select_range_count,
				  &LOCK_status);
5769 5770 5771
	  }
	  else
	  {
5772
	    join->thd->server_status|=SERVER_QUERY_NO_INDEX_USED;
unknown's avatar
af  
unknown committed
5773
	    if (statistics)
5774 5775
	      statistic_increment(join->thd->status_var.select_scan_count,
				  &LOCK_status);
5776 5777 5778 5779 5780 5781
	  }
	}
	else
	{
	  if (tab->select && tab->select->quick)
	  {
unknown's avatar
af  
unknown committed
5782
	    if (statistics)
5783 5784
	      statistic_increment(join->thd->status_var.select_full_range_join_count,
				  &LOCK_status);
5785 5786 5787
	  }
	  else
	  {
5788
	    join->thd->server_status|=SERVER_QUERY_NO_INDEX_USED;
unknown's avatar
af  
unknown committed
5789
	    if (statistics)
5790 5791
	      statistic_increment(join->thd->status_var.select_full_join_count,
				  &LOCK_status);
5792 5793
	  }
	}
unknown's avatar
unknown committed
5794
	if (!table->no_keyread)
unknown's avatar
unknown committed
5795
	{
unknown's avatar
unknown committed
5796
	  if (tab->select && tab->select->quick &&
5797
              tab->select->quick->index != MAX_KEY && //not index_merge
5798
	      table->used_keys.is_set(tab->select->quick->index))
unknown's avatar
unknown committed
5799 5800 5801 5802
	  {
	    table->key_read=1;
	    table->file->extra(HA_EXTRA_KEYREAD);
	  }
unknown's avatar
af  
unknown committed
5803 5804
	  else if (!table->used_keys.is_clear_all() &&
		   !(tab->select && tab->select->quick))
unknown's avatar
unknown committed
5805
	  {					// Only read index tree
unknown's avatar
unknown committed
5806
	    tab->index=find_shortest_key(table, & table->used_keys);
5807
	    tab->read_first_record= join_read_first;
unknown's avatar
unknown committed
5808 5809
	    tab->type=JT_NEXT;		// Read with index_first / index_next
	  }
unknown's avatar
unknown committed
5810 5811 5812 5813 5814 5815 5816 5817 5818 5819 5820 5821 5822 5823 5824 5825
	}
      }
      break;
    default:
      DBUG_PRINT("error",("Table type %d found",tab->type)); /* purecov: deadcode */
      break;					/* purecov: deadcode */
    case JT_UNKNOWN:
    case JT_MAYBE_REF:
      abort();					/* purecov: deadcode */
    }
  }
  join->join_tab[join->tables-1].next_select=0; /* Set by do_select */
  DBUG_VOID_RETURN;
}


unknown's avatar
unknown committed
5826 5827 5828 5829 5830 5831 5832 5833 5834 5835 5836 5837 5838 5839 5840 5841 5842 5843 5844 5845 5846 5847
/*
  Give error if we some tables are done with a full join

  SYNOPSIS
    error_if_full_join()
    join		Join condition

  USAGE
   This is used by multi_table_update and multi_table_delete when running
   in safe mode

 RETURN VALUES
   0	ok
   1	Error (full join used)
*/

bool error_if_full_join(JOIN *join)
{
  for (JOIN_TAB *tab=join->join_tab, *end=join->join_tab+join->tables;
       tab < end;
       tab++)
  {
5848
    if (tab->type == JT_ALL && (!tab->select || !tab->select->quick))
unknown's avatar
unknown committed
5849
    {
unknown's avatar
unknown committed
5850 5851
      my_message(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE,
                 ER(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE), MYF(0));
unknown's avatar
unknown committed
5852 5853 5854 5855 5856 5857 5858
      return(1);
    }
  }
  return(0);
}


unknown's avatar
af  
unknown committed
5859 5860 5861 5862 5863 5864 5865 5866 5867 5868 5869 5870 5871 5872 5873 5874 5875 5876 5877 5878 5879 5880
/*
  cleanup JOIN_TAB

  SYNOPSIS
    JOIN_TAB::cleanup()
*/

void JOIN_TAB::cleanup()
{
  delete select;
  select= 0;
  delete quick;
  quick= 0;
  x_free(cache.buff);
  cache.buff= 0;
  if (table)
  {
    if (table->key_read)
    {
      table->key_read= 0;
      table->file->extra(HA_EXTRA_NO_KEYREAD);
    }
unknown's avatar
unknown committed
5881
    table->file->ha_index_or_rnd_end();
unknown's avatar
af  
unknown committed
5882 5883 5884 5885 5886 5887 5888 5889 5890 5891
    /*
      We need to reset this for next select
      (Tested in part_of_refkey)
    */
    table->reginfo.join_tab= 0;
  }
  end_read_record(&read_record);
}


5892 5893 5894 5895 5896 5897 5898 5899 5900 5901 5902 5903 5904
/*
  Free resources of given join

  SYNOPSIS
    JOIN::join_free()
    fill - true if we should free all resources, call with full==1 should be
           last, before it this function can be called with full==0

  NOTE: with subquery this function definitely will be called several times,
    but even for simple query it can be called several times.
*/
void
JOIN::join_free(bool full)
unknown's avatar
unknown committed
5905 5906
{
  JOIN_TAB *tab,*end;
unknown's avatar
unknown committed
5907
  DBUG_ENTER("JOIN::join_free");
unknown's avatar
unknown committed
5908

unknown's avatar
unknown committed
5909 5910 5911
  full= full || (!select_lex->uncacheable &&
                 !thd->lex->subqueries &&
                 !thd->lex->describe); // do not cleanup too early on EXPLAIN
unknown's avatar
unknown committed
5912

5913
  if (table)
unknown's avatar
unknown committed
5914
  {
5915 5916 5917 5918
    /*
      Only a sorted table may be cached.  This sorted table is always the
      first non const table in join->table
    */
5919
    if (tables > const_tables) // Test for not-const tables
unknown's avatar
unknown committed
5920
    {
5921 5922
      free_io_cache(table[const_tables]);
      filesort_free_buffers(table[const_tables]);
unknown's avatar
unknown committed
5923
    }
5924 5925 5926

    for (SELECT_LEX_UNIT *unit= select_lex->first_inner_unit(); unit;
         unit= unit->next_unit())
5927
    {
5928 5929 5930 5931 5932
      JOIN *join;
      for (SELECT_LEX *sl= unit->first_select_in_union(); sl;
           sl= sl->next_select())
        if ((join= sl->join))
          join->join_free(full);
5933
    }
5934 5935

    if (full)
unknown's avatar
unknown committed
5936
    {
5937
      for (tab= join_tab, end= tab+tables; tab != end; tab++)
unknown's avatar
af  
unknown committed
5938
	tab->cleanup();
5939
      table= 0;
unknown's avatar
unknown committed
5940
      tables= 0;
unknown's avatar
unknown committed
5941
    }
unknown's avatar
unknown committed
5942
    else
5943
    {
5944
      for (tab= join_tab, end= tab+tables; tab != end; tab++)
unknown's avatar
unknown committed
5945
      {
5946 5947
	if (tab->table)
	    tab->table->file->ha_index_or_rnd_end();
unknown's avatar
unknown committed
5948
      }
5949
    }
unknown's avatar
unknown committed
5950
  }
5951

5952 5953 5954 5955
  /*
    We are not using tables anymore
    Unlock all tables. We may be in an INSERT .... SELECT statement.
  */
unknown's avatar
unknown committed
5956
  if (full && lock && thd->lock && !(select_options & SELECT_NO_UNLOCK) &&
5957
      !select_lex->subquery_in_having)
unknown's avatar
unknown committed
5958
  {
5959 5960 5961 5962 5963 5964 5965
    // TODO: unlock tables even if the join isn't top level select in the tree
    if (select_lex == (thd->lex->unit.fake_select_lex ?
                       thd->lex->unit.fake_select_lex : &thd->lex->select_lex))
    {
      mysql_unlock_read_tables(thd, lock);        // Don't free join->lock
      lock=0;
    }
unknown's avatar
unknown committed
5966
  }
5967

5968 5969
  if (full)
  {
5970
    group_fields.delete_elements();
5971 5972 5973 5974
    /*
      We can't call delete_elements() on copy_funcs as this will cause
      problems in free_elements() as some of the elements are then deleted.
    */
unknown's avatar
unknown committed
5975
    tmp_table_param.copy_funcs.empty();
5976
    tmp_table_param.cleanup();
5977
  }
unknown's avatar
unknown committed
5978
  DBUG_VOID_RETURN;
unknown's avatar
unknown committed
5979 5980 5981 5982
}


/*****************************************************************************
5983 5984 5985 5986 5987 5988 5989 5990 5991 5992 5993 5994 5995
  Remove the following expressions from ORDER BY and GROUP BY:
  Constant expressions
  Expression that only uses tables that are of type EQ_REF and the reference
  is in the ORDER list or if all refereed tables are of the above type.

  In the following, the X field can be removed:
  SELECT * FROM t1,t2 WHERE t1.a=t2.a ORDER BY t1.a,t2.X
  SELECT * FROM t1,t2,t3 WHERE t1.a=t2.a AND t2.b=t3.b ORDER BY t1.a,t3.X

  These can't be optimized:
  SELECT * FROM t1,t2 WHERE t1.a=t2.a ORDER BY t2.X,t1.a
  SELECT * FROM t1,t2 WHERE t1.a=t2.a AND t1.b=t2.b ORDER BY t1.a,t2.c
  SELECT * FROM t1,t2 WHERE t1.a=t2.a ORDER BY t2.b,t1.a
unknown's avatar
unknown committed
5996 5997 5998 5999 6000 6001 6002 6003 6004 6005 6006 6007 6008 6009 6010 6011 6012 6013 6014 6015 6016 6017 6018 6019
*****************************************************************************/

static bool
eq_ref_table(JOIN *join, ORDER *start_order, JOIN_TAB *tab)
{
  if (tab->cached_eq_ref_table)			// If cached
    return tab->eq_ref_table;
  tab->cached_eq_ref_table=1;
  if (tab->type == JT_CONST)			// We can skip const tables
    return (tab->eq_ref_table=1);		/* purecov: inspected */
  if (tab->type != JT_EQ_REF)
    return (tab->eq_ref_table=0);		// We must use this
  Item **ref_item=tab->ref.items;
  Item **end=ref_item+tab->ref.key_parts;
  uint found=0;
  table_map map=tab->table->map;

  for (; ref_item != end ; ref_item++)
  {
    if (! (*ref_item)->const_item())
    {						// Not a const ref
      ORDER *order;
      for (order=start_order ; order ; order=order->next)
      {
6020
	if ((*ref_item)->eq(order->item[0],0))
unknown's avatar
unknown committed
6021 6022 6023 6024 6025
	  break;
      }
      if (order)
      {
	found++;
unknown's avatar
unknown committed
6026
	DBUG_ASSERT(!(order->used & map));
unknown's avatar
unknown committed
6027 6028 6029 6030 6031 6032 6033 6034
	order->used|=map;
	continue;				// Used in ORDER BY
      }
      if (!only_eq_ref_tables(join,start_order, (*ref_item)->used_tables()))
	return (tab->eq_ref_table=0);
    }
  }
  /* Check that there was no reference to table before sort order */
6035
  for (; found && start_order ; start_order=start_order->next)
unknown's avatar
unknown committed
6036 6037 6038 6039 6040 6041 6042 6043 6044 6045 6046 6047 6048 6049 6050 6051 6052
  {
    if (start_order->used & map)
    {
      found--;
      continue;
    }
    if (start_order->depend_map & map)
      return (tab->eq_ref_table=0);
  }
  return tab->eq_ref_table=1;
}


static bool
only_eq_ref_tables(JOIN *join,ORDER *order,table_map tables)
{
  if (specialflag &  SPECIAL_SAFE_MODE)
6053
    return 0;			// skip this optimize /* purecov: inspected */
unknown's avatar
unknown committed
6054 6055 6056 6057 6058 6059 6060 6061 6062 6063 6064 6065 6066 6067 6068
  for (JOIN_TAB **tab=join->map2table ; tables ; tab++, tables>>=1)
  {
    if (tables & 1 && !eq_ref_table(join, order, *tab))
      return 0;
  }
  return 1;
}


/* Update the dependency map for the tables */

static void update_depend_map(JOIN *join)
{
  JOIN_TAB *join_tab=join->join_tab, *end=join_tab+join->tables;

6069
  for (; join_tab != end ; join_tab++)
unknown's avatar
unknown committed
6070 6071 6072 6073 6074 6075 6076
  {
    TABLE_REF *ref= &join_tab->ref;
    table_map depend_map=0;
    Item **item=ref->items;
    uint i;
    for (i=0 ; i < ref->key_parts ; i++,item++)
      depend_map|=(*item)->used_tables();
unknown's avatar
unknown committed
6077
    ref->depend_map=depend_map & ~OUTER_REF_TABLE_BIT;
6078
    depend_map&= ~OUTER_REF_TABLE_BIT;
6079
    for (JOIN_TAB **tab=join->map2table;
unknown's avatar
unknown committed
6080
	 depend_map ;
6081
	 tab++,depend_map>>=1 )
unknown's avatar
unknown committed
6082 6083
    {
      if (depend_map & 1)
6084
	ref->depend_map|=(*tab)->ref.depend_map;
unknown's avatar
unknown committed
6085 6086 6087 6088 6089 6090 6091 6092 6093
    }
  }
}


/* Update the dependency map for the sort order */

static void update_depend_map(JOIN *join, ORDER *order)
{
6094
  for (; order ; order=order->next)
unknown's avatar
unknown committed
6095 6096 6097 6098
  {
    table_map depend_map;
    order->item[0]->update_used_tables();
    order->depend_map=depend_map=order->item[0]->used_tables();
unknown's avatar
unknown committed
6099 6100
    // Not item_sum(), RAND() and no reference to table outside of sub select
    if (!(order->depend_map & (OUTER_REF_TABLE_BIT | RAND_TABLE_BIT)))
unknown's avatar
unknown committed
6101
    {
6102
      for (JOIN_TAB **tab=join->map2table;
unknown's avatar
unknown committed
6103
	   depend_map ;
6104
	   tab++, depend_map>>=1)
unknown's avatar
unknown committed
6105 6106
      {
	if (depend_map & 1)
6107
	  order->depend_map|=(*tab)->ref.depend_map;
unknown's avatar
unknown committed
6108 6109 6110 6111 6112 6113 6114
      }
    }
  }
}


/*
6115 6116 6117 6118 6119 6120 6121 6122 6123 6124 6125 6126 6127 6128 6129 6130 6131 6132
  Remove all constants and check if ORDER only contains simple expressions

  SYNOPSIS
   remove_const()
   join			Join handler
   first_order		List of SORT or GROUP order
   cond			WHERE statement
   change_list		Set to 1 if we should remove things from list
			If this is not set, then only simple_order is
                        calculated   
   simple_order		Set to 1 if we are only using simple expressions

  RETURN
    Returns new sort order

    simple_order is set to 1 if sort_order only uses fields from head table
    and the head table is not a LEFT JOIN table

unknown's avatar
unknown committed
6133 6134 6135
*/

static ORDER *
6136 6137
remove_const(JOIN *join,ORDER *first_order, COND *cond,
             bool change_list, bool *simple_order)
unknown's avatar
unknown committed
6138 6139
{
  if (join->tables == join->const_tables)
6140 6141
    return change_list ? 0 : first_order;		// No need to sort

unknown's avatar
unknown committed
6142 6143 6144 6145
  ORDER *order,**prev_ptr;
  table_map first_table= join->join_tab[join->const_tables].table->map;
  table_map not_const_tables= ~join->const_table_map;
  table_map ref;
6146 6147
  DBUG_ENTER("remove_const");

unknown's avatar
unknown committed
6148
  prev_ptr= &first_order;
unknown's avatar
unknown committed
6149
  *simple_order= *join->join_tab[join->const_tables].on_expr_ref ? 0 : 1;
unknown's avatar
unknown committed
6150 6151 6152 6153 6154 6155 6156 6157 6158 6159 6160 6161

  /* NOTE: A variable of not_const_tables ^ first_table; breaks gcc 2.7 */

  update_depend_map(join, first_order);
  for (order=first_order; order ; order=order->next)
  {
    table_map order_tables=order->item[0]->used_tables();
    if (order->item[0]->with_sum_func)
      *simple_order=0;				// Must do a temp table to sort
    else if (!(order_tables & not_const_tables))
    {
      DBUG_PRINT("info",("removing: %s", order->item[0]->full_name()));
unknown's avatar
unknown committed
6162
      continue;					// skip const item
unknown's avatar
unknown committed
6163 6164 6165
    }
    else
    {
unknown's avatar
unknown committed
6166
      if (order_tables & (RAND_TABLE_BIT | OUTER_REF_TABLE_BIT))
unknown's avatar
unknown committed
6167 6168 6169 6170 6171 6172 6173 6174 6175 6176 6177
	*simple_order=0;
      else
      {
	Item *comp_item=0;
	if (cond && const_expression_in_where(cond,order->item[0], &comp_item))
	{
	  DBUG_PRINT("info",("removing: %s", order->item[0]->full_name()));
	  continue;
	}
	if ((ref=order_tables & (not_const_tables ^ first_table)))
	{
unknown's avatar
unknown committed
6178 6179
	  if (!(order_tables & first_table) &&
              only_eq_ref_tables(join,first_order, ref))
unknown's avatar
unknown committed
6180 6181 6182 6183 6184 6185 6186 6187
	  {
	    DBUG_PRINT("info",("removing: %s", order->item[0]->full_name()));
	    continue;
	  }
	  *simple_order=0;			// Must do a temp table to sort
	}
      }
    }
unknown's avatar
unknown committed
6188 6189
    if (change_list)
      *prev_ptr= order;				// use this entry
unknown's avatar
unknown committed
6190 6191
    prev_ptr= &order->next;
  }
unknown's avatar
unknown committed
6192 6193 6194
  if (change_list)
    *prev_ptr=0;
  if (prev_ptr == &first_order)			// Nothing to sort/group
unknown's avatar
unknown committed
6195 6196 6197 6198 6199
    *simple_order=1;
  DBUG_PRINT("exit",("simple_order: %d",(int) *simple_order));
  DBUG_RETURN(first_order);
}

6200

unknown's avatar
unknown committed
6201
static int
6202 6203
return_zero_rows(JOIN *join, select_result *result,TABLE_LIST *tables,
		 List<Item> &fields, bool send_row, uint select_options,
unknown's avatar
unknown committed
6204 6205
		 const char *info, Item *having, Procedure *procedure,
		 SELECT_LEX_UNIT *unit)
unknown's avatar
unknown committed
6206 6207 6208 6209
{
  DBUG_ENTER("return_zero_rows");

  if (select_options & SELECT_DESCRIBE)
6210
  {
unknown's avatar
af  
unknown committed
6211
    select_describe(join, FALSE, FALSE, FALSE, info);
unknown's avatar
unknown committed
6212 6213
    DBUG_RETURN(0);
  }
unknown's avatar
unknown committed
6214

6215 6216
  join->join_free(0);

unknown's avatar
unknown committed
6217 6218
  if (send_row)
  {
6219
    for (TABLE_LIST *table= tables; table; table= table->next_leaf)
unknown's avatar
unknown committed
6220
      mark_as_null_row(table->table);		// All fields are NULL
6221
    if (having && having->val_int() == 0)
unknown's avatar
unknown committed
6222 6223
      send_row=0;
  }
6224 6225
  if (!(result->send_fields(fields,
                              Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)))
unknown's avatar
unknown committed
6226 6227
  {
    if (send_row)
unknown's avatar
unknown committed
6228 6229 6230 6231 6232
    {
      List_iterator_fast<Item> it(fields);
      Item *item;
      while ((item= it++))
	item->no_rows_in_result();
unknown's avatar
unknown committed
6233
      result->send_data(fields);
unknown's avatar
unknown committed
6234
    }
6235
    result->send_eof();				// Should be safe
unknown's avatar
unknown committed
6236
  }
6237 6238
  /* Update results for FOUND_ROWS */
  join->thd->limit_found_rows= join->thd->examined_row_count= 0;
unknown's avatar
unknown committed
6239 6240 6241 6242 6243 6244 6245 6246 6247 6248 6249
  DBUG_RETURN(0);
}


static void clear_tables(JOIN *join)
{
  for (uint i=0 ; i < join->tables ; i++)
    mark_as_null_row(join->table[i]);		// All fields are NULL
}

/*****************************************************************************
6250 6251 6252 6253 6254 6255
  Make som simple condition optimization:
  If there is a test 'field = const' change all refs to 'field' to 'const'
  Remove all dummy tests 'item = item', 'const op const'.
  Remove all 'item is NULL', when item can never be null!
  item->marker should be 0 for all items on entry
  Return in cond_value FALSE if condition is impossible (1 = 2)
unknown's avatar
unknown committed
6256 6257 6258 6259
*****************************************************************************/

class COND_CMP :public ilink {
public:
unknown's avatar
unknown committed
6260 6261 6262 6263
  static void *operator new(size_t size)
  {
    return (void*) sql_alloc((uint) size);
  }
unknown's avatar
unknown committed
6264
  static void operator delete(void *ptr __attribute__((unused)),
unknown's avatar
unknown committed
6265 6266
                              size_t size __attribute__((unused)))
  { TRASH(ptr, size); }
unknown's avatar
unknown committed
6267 6268 6269 6270 6271 6272 6273 6274 6275 6276 6277 6278 6279

  Item *and_level;
  Item_func *cmp_func;
  COND_CMP(Item *a,Item_func *b) :and_level(a),cmp_func(b) {}
};

#ifdef __GNUC__
template class I_List<COND_CMP>;
template class I_List_iterator<COND_CMP>;
template class List<Item_func_match>;
template class List_iterator<Item_func_match>;
#endif

6280 6281 6282 6283 6284 6285 6286 6287

/* 
  Find the multiple equality predicate containing a field
 
  SYNOPSIS
    find_item_equal()
    cond_equal          multiple equalities to search in
    field               field to look for
unknown's avatar
unknown committed
6288
    inherited_fl  :out  set up to TRUE if multiple equality is found
6289 6290 6291 6292 6293 6294 6295 6296 6297 6298 6299 6300 6301 6302 6303 6304 6305 6306 6307 6308 6309 6310 6311 6312 6313 6314 6315
                        on upper levels (not on current level of cond_equal) 

  DESCRIPTION
    The function retrieves the multiple equalities accessed through
    the con_equal structure from current level and up looking for
    an equality containing field. It stops retrieval as soon as the equality
    is found and set up inherited_fl to TRUE if it's found on upper levels.

  RETURN
    Item_equal for the found multiple equality predicate if a success;
    NULL - otherwise.
*/

Item_equal *find_item_equal(COND_EQUAL *cond_equal, Field *field,
                            bool *inherited_fl)
{
  Item_equal *item= 0;
  bool in_upper_level= FALSE;
  while (cond_equal)
  {
    List_iterator_fast<Item_equal> li(cond_equal->current_level);
    while ((item= li++))
    {
      if (item->contains(field))
        goto finish;
    }
    in_upper_level= TRUE;
unknown's avatar
unknown committed
6316
    cond_equal= cond_equal->upper_levels;
6317 6318 6319
  }
  in_upper_level= FALSE;
finish:
unknown's avatar
unknown committed
6320
  *inherited_fl= in_upper_level;
6321 6322
  return item;
}
unknown's avatar
unknown committed
6323

6324 6325 6326 6327 6328 6329 6330 6331 6332 6333 6334 6335
  
/* 
  Check whether an item is a simple equality predicate and if so
  create/find a multiple equality for this predicate

  SYNOPSIS
    check_equality()
    item       item to check
    cond_equal multiple equalities that must hold together with the predicate

  DESCRIPTION
    This function first checks whether an item is a simple equality i.e.
unknown's avatar
unknown committed
6336 6337
    the one that equates a field with another field or a constant
    (item=constant_item or item=field_item).
6338
    If this is the case the function looks a for a multiple equality
unknown's avatar
unknown committed
6339 6340 6341 6342 6343 6344 6345 6346 6347
    in the lists referenced directly or indirectly by cond_equal inferring
    the given simple equality. If it doesn't find any, it builds a multiple
    equality that covers the predicate, i.e. the predicate can be inferred
    from it.
    The built multiple equality could be obtained in such a way:
    create a binary  multiple equality equivalent to the predicate, then
    merge it, if possible, with one of old multiple equalities.
    This guarantees that the set of multiple equalities covering equality
    predicates will
6348 6349
    be minimal.

unknown's avatar
unknown committed
6350 6351 6352 6353 6354 6355 6356 6357 6358 6359 6360
  EXAMPLE
    For the where condition
    WHERE a=b AND b=c AND
          (b=2 OR f=e)
    the check_equality will be called for the following equality
    predicates a=b, b=c, b=2 and f=e.
    For a=b it will be called with *cond_equal=(0,[]) and will transform
    *cond_equal into (0,[Item_equal(a,b)]). 
    For b=c it will be called with *cond_equal=(0,[Item_equal(a,b)])
    and will transform *cond_equal into CE=(0,[Item_equal(a,b,c)]).
    For b=2 it will be called with *cond_equal=(ptr(CE),[])
6361
    and will transform *cond_equal into (ptr(CE),[Item_equal(2,a,b,c)]).
unknown's avatar
unknown committed
6362
    For f=e it will be called with *cond_equal=(ptr(CE), [])
6363
    and will transform *cond_equal into (ptr(CE),[Item_equal(f,e)]).
unknown's avatar
unknown committed
6364

6365 6366 6367 6368
  NOTES
    Now only fields that have the same type defintions (verified by
    the Field::eq_def method) are placed to the same multiple equalities.
    Because of this some equality predicates are not eliminated and
unknown's avatar
unknown committed
6369
    can be used in the constant propagation procedure.
6370 6371 6372 6373 6374 6375
    We could weeken the equlity test as soon as at least one of the 
    equal fields is to be equal to a constant. It would require a 
    more complicated implementation: we would have to store, in
    general case, its own constant for each fields from the multiple
    equality. But at the same time it would allow us to get rid
    of constant propagation completely: it would be done by the call
unknown's avatar
unknown committed
6376
    to build_equal_items_for_cond.
6377 6378 6379 6380 6381 6382
    
  IMPLEMENTATION
    The implementation does not follow exactly the above rules to
    build a new multiple equality for the equality predicate.
    If it processes the equality of the form field1=field2, it
    looks for multiple equalities me1 containig field1 and me2 containing
unknown's avatar
unknown committed
6383
    field2. If only one of them is found the fuction expands it with
6384 6385 6386 6387 6388 6389 6390 6391 6392 6393 6394 6395 6396 6397 6398 6399 6400 6401 6402 6403 6404 6405 6406 6407 6408 6409 6410
    the lacking field. If multiple equalities for both fields are
    found they are merged. If both searches fail a new multiple equality
    containing just field1 and field2 is added to the existing
    multiple equalities.
    If the function processes the predicate of the form field1=const,
    it looks for a multiple equality containing field1. If found, the 
    function checks the constant of the multiple equality. If the value
    is unknown, it is setup to const. Otherwise the value is compared with
    const and the evaluation of the equality predicate is performed.
    When expanding/merging equality predicates from the upper levels
    the function first copies them for the current level. It looks
    acceptable, as this happens rarely. The implementation without
    copying would be much more complicated.

  RETURN
    TRUE  - if the predicate is a simple equality predicate
    FALSE - otherwise
*/

static bool check_equality(Item *item, COND_EQUAL *cond_equal)
{
  if (item->type() == Item::FUNC_ITEM &&
         ((Item_func*) item)->functype() == Item_func::EQ_FUNC)
  {
    Item *left_item= ((Item_func*) item)->arguments()[0];
    Item *right_item= ((Item_func*) item)->arguments()[1];
    if (left_item->type() == Item::FIELD_ITEM &&
6411 6412 6413
        right_item->type() == Item::FIELD_ITEM &&
        !((Item_field*)left_item)->depended_from &&
        !((Item_field*)right_item)->depended_from)
6414 6415 6416 6417 6418 6419 6420 6421 6422
    {
      /* The predicate the form field1=field2 is processed */

      Field *left_field= ((Item_field*) left_item)->field;
      Field *right_field= ((Item_field*) right_item)->field;

      if (!left_field->eq_def(right_field))
        return FALSE;

unknown's avatar
unknown committed
6423
      if (left_field->eq(right_field))  /* f = f */
6424 6425 6426 6427 6428 6429 6430 6431 6432 6433 6434 6435 6436
        return TRUE;
      
      /* Search for multiple equalities containing field1 and/or field2 */
      bool left_copyfl, right_copyfl;
      Item_equal *left_item_equal=
                 find_item_equal(cond_equal, left_field, &left_copyfl);
      Item_equal *right_item_equal= 
                 find_item_equal(cond_equal, right_field, &right_copyfl);

      if (left_item_equal && left_item_equal == right_item_equal)
      {
        /* 
           The equality predicate is inference of one of the existing
unknown's avatar
unknown committed
6437 6438
           multiple equalities, i.e the condition is already covered
           by upper level equalities
6439 6440 6441 6442 6443 6444 6445
        */
          return TRUE;
      }
      
      /* Copy the found multiple equalities at the current level if needed */
      if (left_copyfl)
      {
unknown's avatar
unknown committed
6446
        /* left_item_equal of an upper level contains left_item */
6447 6448 6449 6450 6451
        left_item_equal= new Item_equal(left_item_equal);
        cond_equal->current_level.push_back(left_item_equal);
      }
      if (right_copyfl)
      {
unknown's avatar
unknown committed
6452
        /* right_item_equal of an upper level contains right_item */
6453 6454 6455 6456 6457 6458
        right_item_equal= new Item_equal(right_item_equal);
        cond_equal->current_level.push_back(right_item_equal);
      }

      if (left_item_equal)
      { 
unknown's avatar
unknown committed
6459
        /* left item was found in the current or one of the upper levels */
6460 6461 6462 6463 6464 6465 6466 6467 6468 6469 6470 6471 6472 6473
        if (! right_item_equal)
          left_item_equal->add((Item_field *) right_item);
        else
        {
          /* Merge two multiple equalities forming a new one */
          left_item_equal->merge(right_item_equal);
          /* Remove the merged multiple equality from the list */
          List_iterator<Item_equal> li(cond_equal->current_level);
          while ((li++) != right_item_equal);
          li.remove();
        }
      }
      else
      { 
unknown's avatar
unknown committed
6474
        /* left item was not found neither the current nor in upper levels  */
6475 6476 6477 6478
         if (right_item_equal)
           right_item_equal->add((Item_field *) left_item);
         else 
         {
unknown's avatar
unknown committed
6479
           /* None of the fields was found in multiple equalities */
6480 6481 6482 6483 6484 6485 6486
           Item_equal *item= new Item_equal((Item_field *) left_item,
                                            (Item_field *) right_item);
           cond_equal->current_level.push_back(item);
         }
      }
      return TRUE;
    }
unknown's avatar
unknown committed
6487

6488 6489 6490 6491
    {
      /* The predicate of the form field=const/const=field is processed */
      Item *const_item= 0;
      Item_field *field_item= 0;
6492 6493
      if (left_item->type() == Item::FIELD_ITEM &&
          !((Item_field*)left_item)->depended_from &&
6494 6495 6496 6497 6498
          right_item->const_item())
      {
        field_item= (Item_field*) left_item;
        const_item= right_item;
      }
6499 6500
      else if (right_item->type() == Item::FIELD_ITEM &&
               !((Item_field*)right_item)->depended_from &&
6501 6502 6503 6504 6505 6506 6507 6508 6509
               left_item->const_item())
      {
        field_item= (Item_field*) right_item;
        const_item= left_item;
      }
      if (const_item &&
          field_item->result_type() == const_item->result_type())
      {
        bool copyfl;
unknown's avatar
unknown committed
6510

6511 6512 6513 6514 6515 6516 6517
        if (field_item->result_type() == STRING_RESULT)
        {
          CHARSET_INFO *cs= ((Field_str*) field_item->field)->charset();
          if ((cs != ((Item_cond *) item)->compare_collation()) ||
              !cs->coll->propagate(cs, 0, 0))
            return FALSE;
        }
unknown's avatar
unknown committed
6518

6519 6520 6521 6522 6523 6524 6525 6526 6527 6528 6529 6530 6531 6532 6533 6534 6535 6536 6537 6538 6539 6540 6541 6542 6543 6544 6545 6546 6547 6548 6549 6550
        Item_equal *item_equal = find_item_equal(cond_equal,
                                                 field_item->field, &copyfl);
        if (copyfl)
        {
          item_equal= new Item_equal(item_equal);
          cond_equal->current_level.push_back(item_equal);
        }
        if (item_equal)
        {
          /* 
            The flag cond_false will be set to 1 after this, if item_equal
            already contains a constant and its value is  not equal to
            the value of const_item.
          */
          item_equal->add(const_item);
        }
        else
        {
          item_equal= new Item_equal(const_item, field_item);
          cond_equal->current_level.push_back(item_equal);
        }
        return TRUE;
      }
    }
  }
  return FALSE;
}

/* 
  Replace all equality predicates in a condition by multiple equality items

  SYNOPSIS
unknown's avatar
unknown committed
6551
    build_equal_items_for_cond()
6552 6553 6554 6555 6556 6557 6558 6559 6560
    cond       condition(expression) where to make replacement
    inherited  path to all inherited multiple equality items

  DESCRIPTION
    At each 'and' level the function detects items for equality predicates
    and replaced them by a set of multiple equality items of class Item_equal,
    taking into account inherited equalities from upper levels. 
    If an equality predicate is used not in a conjunction it's just
    replaced by a multiple equality predicate.
unknown's avatar
unknown committed
6561 6562 6563 6564 6565
    For each 'and' level the function set a pointer to the inherited
    multiple equalities in the cond_equal field of the associated
    object of the type Item_cond_and.   
    The function also traverses the cond tree and and for each field reference
    sets a pointer to the multiple equality item containing the field, if there
6566
    is any. If this multiple equality equates fields to a constant the
unknown's avatar
unknown committed
6567 6568 6569 6570 6571
    function replace the field reference by the constant.
    The function also determines the maximum number of members in 
    equality lists of each Item_cond_and object assigning it to
    cond_equal->max_members of this object and updating accordingly
    the upper levels COND_EQUAL structures.  
6572 6573 6574 6575 6576 6577 6578

  NOTES
    Multiple equality predicate =(f1,..fn) is equivalent to the conjuction of
    f1=f2, .., fn-1=fn. It substitutes any inference from these
    equality predicates that is equivalent to the conjunction.
    Thus, =(a1,a2,a3) can substitute for ((a1=a3) AND (a2=a3) AND (a2=a1)) as
    it is equivalent to ((a1=a2) AND (a2=a3)).
unknown's avatar
unknown committed
6579
    The function always makes a substitution of all equality predicates occured
6580 6581 6582 6583 6584 6585
    in a conjuction for a minimal set of multiple equality predicates.
    This set can be considered as a canonical representation of the
    sub-conjunction of the equality predicates.
    E.g. (t1.a=t2.b AND t2.b>5 AND t1.a=t3.c) is replaced by 
    (=(t1.a,t2.b,t3.c) AND t2.b>5), not by
    (=(t1.a,t2.b) AND =(t1.a,t3.c) AND t2.b>5);
unknown's avatar
unknown committed
6586
    while (t1.a=t2.b AND t2.b>5 AND t3.c=t4.d) is replaced by
6587 6588 6589 6590 6591 6592 6593 6594 6595 6596 6597 6598 6599
    (=(t1.a,t2.b) AND =(t3.c=t4.d) AND t2.b>5),
    but if additionally =(t4.d,t2.b) is inherited, it
    will be replaced by (=(t1.a,t2.b,t3.c,t4.d) AND t2.b>5)

  IMPLEMENTATION
    The function performs the substitution in a recursive descent by
    the condtion tree, passing to the next AND level a chain of multiple
    equality predicates which have been built at the upper levels.
    The Item_equal items built at the level are attached to other 
    non-equality conjucts as a sublist. The pointer to the inherited
    multiple equalities is saved in the and condition object (Item_cond_and).
    This chain allows us for any field reference occurence easyly to find a 
    multiple equality that must be held for this occurence.
unknown's avatar
unknown committed
6600 6601 6602 6603 6604 6605 6606
    For each AND level we do the following:
    - scan it for all equality predicate (=) items
    - join them into disjoint Item_equal() groups
    - process the included OR conditions recursively to do the same for 
      lower AND levels. 
    We need to do things in this order as lower AND levels need to know about
    all possible Item_equal objects in upper levels.
6607 6608 6609 6610 6611

  RETURN
    pointer to the transformed condition
*/

unknown's avatar
unknown committed
6612
static COND *build_equal_items_for_cond(COND *cond,
6613 6614
                                        COND_EQUAL *inherited)
{
unknown's avatar
unknown committed
6615 6616
  Item_equal *item_equal;
  uint members;
6617
  COND_EQUAL cond_equal;
unknown's avatar
unknown committed
6618
  cond_equal.upper_levels= inherited;
6619 6620 6621 6622 6623 6624 6625 6626 6627 6628 6629 6630 6631 6632 6633

  if (cond->type() == Item::COND_ITEM)
  {
    bool and_level= ((Item_cond*) cond)->functype() ==
      Item_func::COND_AND_FUNC;
    List<Item> *args= ((Item_cond*) cond)->argument_list();
    
    List_iterator<Item> li(*args);
    Item *item;

    if (and_level)
    {
      /*
         Retrieve all conjucts of this level detecting the equality
         that are subject to substitution by multiple equality items and
unknown's avatar
unknown committed
6634
         removing each such predicate from the conjunction after having 
6635 6636 6637 6638
         found/created a multiple equality whose inference the predicate is.
     */      
      while ((item= li++))
      {
6639 6640 6641 6642 6643
        /*
          PS/SP note: we can safely remove a node from AND-OR
          structure here because it's restored before each
          re-execution of any prepared statement/stored procedure.
        */
6644 6645 6646 6647 6648
        if (check_equality(item, &cond_equal))
          li.remove();
      }

      List_iterator_fast<Item_equal> it(cond_equal.current_level);
unknown's avatar
unknown committed
6649
      while ((item_equal= it++))
6650
      {
unknown's avatar
unknown committed
6651 6652 6653 6654 6655 6656 6657 6658 6659 6660 6661 6662 6663 6664 6665 6666 6667
        item_equal->fix_length_and_dec();
        item_equal->update_used_tables();
        members= item_equal->members();
        if (cond_equal.max_members < members)
          cond_equal.max_members= members; 
      }
      members= cond_equal.max_members;
      if (inherited && inherited->max_members < members)
      {
        do
        {
	  inherited->max_members= members;
          inherited= inherited->upper_levels;
        }
        while (inherited);
      }

6668 6669 6670 6671 6672 6673 6674
      ((Item_cond_and*)cond)->cond_equal= cond_equal;
      inherited= &(((Item_cond_and*)cond)->cond_equal);
    }
    /*
       Make replacement of equality predicates for lower levels
       of the condition expression.
    */
unknown's avatar
unknown committed
6675 6676
    li.rewind();
    while((item= li++))
6677 6678
    { 
      Item *new_item;
unknown's avatar
unknown committed
6679
      if ((new_item = build_equal_items_for_cond(item, inherited))!= item)
6680 6681
      {
        /* This replacement happens only for standalone equalities */
6682 6683 6684 6685 6686
        /*
          This is ok with PS/SP as the replacement is done for
          arguments of an AND/OR item, which are restored for each
          execution of PS/SP.
        */
unknown's avatar
unknown committed
6687
        li.replace(new_item);
6688 6689 6690 6691 6692 6693 6694
      }
    }
    if (and_level)
      args->concat((List<Item> *)&cond_equal.current_level);
  }
  else if (cond->type() == Item::FUNC_ITEM)
  {
unknown's avatar
unknown committed
6695 6696 6697 6698 6699 6700 6701 6702 6703 6704
    /*
      If an equality predicate forms the whole and level,
      we call it standalone equality and it's processed here.
      E.g. in the following where condition
      WHERE a=5 AND (b=5 or a=c)
      (b=5) and (a=c) are standalone equalities.
      In general we can't leave alone standalone eqalities:
      for WHERE a=b AND c=d AND (b=c OR d=5)
      b=c is replaced by =(a,b,c,d).  
     */
6705 6706 6707
    if (check_equality(cond, &cond_equal) &&
        (item_equal= cond_equal.current_level.pop()))
    {
unknown's avatar
unknown committed
6708 6709
      item_equal->fix_length_and_dec();
      item_equal->update_used_tables();
6710 6711
      return item_equal;
    }
unknown's avatar
unknown committed
6712 6713 6714 6715 6716 6717 6718
    /* 
      For each field reference in cond, not from equalitym predicates,
      set a pointer to the multiple equality if belongs to (if there is any)
    */ 
    cond= cond->transform(&Item::equal_fields_propagator,
                            (byte *) inherited);
    cond->update_used_tables();
6719
  }
unknown's avatar
unknown committed
6720 6721 6722
  return cond;
}

unknown's avatar
unknown committed
6723

unknown's avatar
unknown committed
6724 6725 6726 6727 6728 6729
/* 
  Build multiple equalities for a condition and all on expressions that
  inherit these multiple equalities

  SYNOPSIS
    build_equal_items()
unknown's avatar
unknown committed
6730
    thd			Thread handler
unknown's avatar
unknown committed
6731 6732 6733 6734 6735 6736 6737 6738 6739 6740 6741 6742 6743 6744 6745 6746 6747 6748 6749 6750 6751 6752 6753 6754 6755 6756 6757 6758 6759 6760 6761 6762 6763 6764 6765 6766 6767 6768 6769 6770 6771 6772 6773 6774 6775 6776 6777 6778 6779 6780 6781
    cond                condition to build the multiple equalities for
    inherited           path to all inherited multiple equality items
    join_list           list of join tables to which the condition refers to
    cond_equal_ref :out pointer to the structure to place built equalities in

  DESCRIPTION
    The function first applies the build_equal_items_for_cond function
    to build all multiple equalities for condition cond utilizing equalities
    referred through the parameter inherited. The extended set of
    equalities is returned in the structure referred by the cond_equal_ref
    parameter. After this the function calls itself recursively for
    all on expressions whose direct references can be found in join_list
    and who inherit directly the multiple equalities just having built.

  NOTES
    The on expression used in an outer join operation inherits all equalities
    from the on expression of the embedding join, if there is any, or 
    otherwise - from the where condition.
    This fact is not obvious, but presumably can be proved.
    Consider the following query:
      SELECT * FROM (t1,t2) LEFT JOIN (t3,t4) ON t1.a=t3.a AND t2.a=t4.a
        WHERE t1.a=t2.a;
    If the on expression in the query inherits =(t1.a,t2.a), then we
    can build the multiple equality =(t1.a,t2.a,t3.a,t4.a) that infers
    the equality t3.a=t4.a. Although the on expression
    t1.a=t3.a AND t2.a=t4.a AND t3.a=t4.a is not equivalent to the one
    in the query the latter can be replaced by the former: the new query
    will return the same result set as the original one.

    Interesting that multiple equality =(t1.a,t2.a,t3.a,t4.a) allows us
    to use t1.a=t3.a AND t3.a=t4.a under the on condition:
      SELECT * FROM (t1,t2) LEFT JOIN (t3,t4) ON t1.a=t3.a AND t3.a=t4.a
        WHERE t1.a=t2.a
    This query equivalent to:
      SELECT * FROM (t1 LEFT JOIN (t3,t4) ON t1.a=t3.a AND t3.a=t4.a),t2
        WHERE t1.a=t2.a
    Similarly the original query can be rewritten to the query:
      SELECT * FROM (t1,t2) LEFT JOIN (t3,t4) ON t2.a=t4.a AND t3.a=t4.a
        WHERE t1.a=t2.a
    that is equivalent to:   
      SELECT * FROM (t2 LEFT JOIN (t3,t4)ON t2.a=t4.a AND t3.a=t4.a), t1
        WHERE t1.a=t2.a
    Thus, applying equalities from the where condition we basically
    can get more freedom in performing join operations.
    Althogh we don't use this property now, it probably makes sense to use 
    it in the future.    
         
  RETURN
    pointer to the transformed condition containing multiple equalities
*/
   
unknown's avatar
unknown committed
6782
static COND *build_equal_items(THD *thd, COND *cond,
unknown's avatar
unknown committed
6783 6784 6785 6786 6787 6788 6789 6790 6791 6792 6793 6794 6795 6796 6797 6798 6799 6800 6801 6802 6803 6804 6805 6806 6807 6808 6809 6810 6811 6812 6813 6814 6815 6816 6817 6818 6819 6820
                               COND_EQUAL *inherited,
                               List<TABLE_LIST> *join_list,
                               COND_EQUAL **cond_equal_ref)
{
  COND_EQUAL *cond_equal= 0;

  if (cond) 
  {
    cond= build_equal_items_for_cond(cond, inherited);
    cond->update_used_tables();
    if (cond->type() == Item::COND_ITEM &&
        ((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
      cond_equal= &((Item_cond_and*) cond)->cond_equal;
    else if (cond->type() == Item::FUNC_ITEM &&
             ((Item_cond*) cond)->functype() == Item_func::MULT_EQUAL_FUNC)
    {
      cond_equal= new COND_EQUAL;
      cond_equal->current_level.push_back((Item_equal *) cond);
    }
  }
  if (cond_equal)
  {
    cond_equal->upper_levels= inherited;
    inherited= cond_equal;
  }
  *cond_equal_ref= cond_equal;

  if (join_list)
  {
    TABLE_LIST *table;
    List_iterator<TABLE_LIST> li(*join_list);

    while ((table= li++))
    {
      if (table->on_expr)
      {
        List<TABLE_LIST> *join_list= table->nested_join ?
	                             &table->nested_join->join_list : NULL;
6821 6822 6823 6824 6825 6826
        /*
          We can modify table->on_expr because its old value will
          be restored before re-execution of PS/SP.
        */
        table->on_expr= build_equal_items(thd, table->on_expr, inherited,
                                          join_list, &table->cond_equal);
unknown's avatar
unknown committed
6827 6828 6829 6830
      }
    }
  }

6831 6832 6833
  return cond;
}    

unknown's avatar
unknown committed
6834

unknown's avatar
unknown committed
6835 6836 6837 6838 6839 6840 6841 6842 6843 6844 6845 6846 6847 6848 6849 6850 6851 6852 6853 6854 6855 6856 6857 6858 6859 6860 6861 6862 6863 6864 6865 6866 6867 6868 6869 6870 6871 6872 6873 6874 6875 6876 6877 6878
/* 
  Compare field items by table order in the execution plan
 
  SYNOPSIS
    compare_fields_by_table_order()
    field1          first field item to compare
    field2          second field item to compare
    table_join_idx  index to tables determining table order    

  DESCRIPTION
    field1 considered as better than field2 if the table containing
    field1 is accessed earlier than the table containing field2.   
    The function finds out what of two fields is better according
    this criteria.

  RETURN
     1, if field1 is better than field2 
    -1, if field2 is better than field1
     0, otherwise
*/

static int compare_fields_by_table_order(Item_field *field1,
                                  Item_field *field2,
                                  void *table_join_idx)
{
  int cmp= 0;
  bool outer_ref= 0;
  if (field2->used_tables() & OUTER_REF_TABLE_BIT)
  {  
    outer_ref= 1;
    cmp= -1;
  }
  if (field2->used_tables() & OUTER_REF_TABLE_BIT)
  {
    outer_ref= 1;
    cmp++;
  }
  if (outer_ref)
    return cmp;
  JOIN_TAB **idx= (JOIN_TAB **) table_join_idx;
  cmp= idx[field2->field->table->tablenr]-idx[field1->field->table->tablenr];
  return cmp < 0 ? -1 : (cmp ? 1 : 0);
}

6879 6880 6881 6882 6883 6884 6885

/* 
  Generate minimal set of simple equalities equivalent to a multiple equality
 
  SYNOPSIS
    eliminate_item_equal()
    cond            condition to add the generated equality to
unknown's avatar
unknown committed
6886
    upper_levels    structure to access multiple equality of upper levels
6887 6888 6889 6890 6891 6892 6893 6894 6895 6896 6897 6898 6899
    item_equal      multiple equality to generate simple equality from     

  DESCRIPTION
    The function retrieves the fields of the multiple equality item
    item_equal and  for each field f:
    - if item_equal contains const it generates the equality f=const_item;
    - otherwise, if f is not the first field, generates the equality
      f=item_equal->get_first().
    All generated equality are added to the cond conjunction.

  NOTES
    Before generating an equality function checks that it has not
    been generated for multiple equalies of the upper levels.
unknown's avatar
unknown committed
6900 6901 6902 6903 6904 6905 6906 6907 6908 6909 6910 6911 6912 6913
    E.g. for the following where condition
    WHERE a=5 AND ((a=b AND b=c) OR  c>4)
    the upper level AND condition will contain =(5,a),
    while the lower level AND condition will contain =(5,a,b,c).
    When splitting =(5,a,b,c) into a separate equality predicates
    we should omit 5=a, as we have it already in the upper level.
    The following where condition gives us a more complicated case:
    WHERE t1.a=t2.b AND t3.c=t4.d AND (t2.b=t3.c OR t4.e>5 ...) AND ...
    Given the tables are accessed in the order t1->t2->t3->t4 for
    the selected query execution plan the lower level multiple
    equality =(t1.a,t2.b,t3.c,t4.d) formally  should be converted to
    t1.a=t2.b AND t1.a=t3.c AND t1.a=t4.d. But t1.a=t2.a will be
    generated for the upper level. Also t3.c=t4.d will be generated there.
    So only t1.a=t3.c should be left in the lower level.
6914 6915 6916 6917 6918
    If cond is equal to 0, then not more then one equality is generated
    and a pointer to it is returned as the result of the function.

  RETURN
    The condition with generated simple equalities or
unknown's avatar
unknown committed
6919 6920
    a pointer to the simple generated equality, if success.
    0, otherwise.
6921 6922
*/

unknown's avatar
unknown committed
6923
static Item *eliminate_item_equal(COND *cond, COND_EQUAL *upper_levels,
6924 6925
                                  Item_equal *item_equal)
{
unknown's avatar
unknown committed
6926 6927
  List<Item> eq_list;
  Item_func_eq *eq_item= 0;
unknown's avatar
unknown committed
6928
  if (((Item *) item_equal)->const_item() && !item_equal->val_int())
unknown's avatar
unknown committed
6929
    return new Item_int((longlong) 0,1); 
6930 6931
  Item *item_const= item_equal->get_const();
  Item_equal_iterator it(*item_equal);
unknown's avatar
unknown committed
6932
  Item *head;
6933 6934 6935 6936 6937 6938 6939 6940 6941 6942
  if (item_const)
    head= item_const;
  else
  {
    head= item_equal->get_first();
    it++;
  }
  Item_field *item_field;
  while ((item_field= it++))
  {
unknown's avatar
unknown committed
6943
    Item_equal *upper= item_field->find_item_equal(upper_levels);
6944 6945 6946
    Item_field *item= item_field;
    if (upper)
    { 
unknown's avatar
unknown committed
6947 6948
      if (item_const && upper->get_const())
        item= 0;
6949 6950 6951 6952 6953
      else
      {
        Item_equal_iterator li(*item_equal);
        while ((item= li++) != item_field)
        {
unknown's avatar
unknown committed
6954
          if (item->find_item_equal(upper_levels) == upper)
6955 6956 6957 6958 6959 6960
            break;
        }
      }
    }
    if (item == item_field)
    {
unknown's avatar
unknown committed
6961 6962 6963 6964 6965 6966
      if (eq_item)
        eq_list.push_back(eq_item);
      eq_item= new Item_func_eq(item_field, head);
      if (!eq_item)
        return 0;
      eq_item->set_cmp_func();
unknown's avatar
unknown committed
6967
      eq_item->quick_fix_field();
unknown's avatar
unknown committed
6968
   }
6969
  }
unknown's avatar
unknown committed
6970 6971

  if (!cond && !eq_list.head())
unknown's avatar
unknown committed
6972 6973 6974
  {
    if (!eq_item)
      return new Item_int((longlong) 1,1);
unknown's avatar
unknown committed
6975
    return eq_item;
unknown's avatar
unknown committed
6976
  }
unknown's avatar
unknown committed
6977

unknown's avatar
unknown committed
6978 6979
  if (eq_item)
    eq_list.push_back(eq_item);
6980
  if (!cond)
unknown's avatar
unknown committed
6981 6982 6983
    cond= new Item_cond_and(eq_list);
  else
    ((Item_cond *) cond)->add_at_head(&eq_list);
unknown's avatar
unknown committed
6984 6985 6986

  cond->quick_fix_field();
  cond->update_used_tables();
unknown's avatar
unknown committed
6987
   
6988 6989 6990 6991 6992 6993 6994 6995 6996 6997 6998
  return cond;
}


/* 
  Substitute every field reference in a condition by the best equal field 
  and eliminate all multiplle equality predicates
 
  SYNOPSIS
    substitute_for_best_equal_field()
    cond            condition to process
unknown's avatar
unknown committed
6999
    cond_equal      multiple equalities to take into consideration
7000 7001 7002 7003 7004 7005 7006 7007 7008 7009 7010 7011 7012 7013 7014 7015 7016 7017 7018 7019 7020 7021 7022 7023 7024
    table_join_idx  index to tables determining field preference

  DESCRIPTION
    The function retrieves the cond condition and for each encountered
    multiple equality predicate it sorts the field references in it
    according to the order of tables specified by the table_join_idx
    parameter. Then it eliminates the multiple equality predicate it
    replacing it by the conjunction of simple equality predicates 
    equating every field from the multiple equality to the first
    field in it, or to the constant, if there is any.
    After this the function retrieves all other conjuncted
    predicates substitute every field reference by the field reference
    to the first equal field or equal constant if there are any.
 
  NOTES
    At the first glance full sort of fields in multiple equality
    seems to be an overkill. Yet it's not the case due to possible
    new fields in multiple equality item of lower levels. We want
    the order in them to comply with the order of upper levels.

  RETURN
    The transformed condition
*/

static COND* substitute_for_best_equal_field(COND *cond,
unknown's avatar
unknown committed
7025
                                             COND_EQUAL *cond_equal,
7026 7027 7028 7029 7030 7031 7032 7033 7034 7035 7036 7037 7038 7039 7040 7041
                                             void *table_join_idx)
{
  Item_equal *item_equal;

  if (cond->type() == Item::COND_ITEM)
  {
    List<Item> *cond_list= ((Item_cond*) cond)->argument_list();

    bool and_level= ((Item_cond*) cond)->functype() ==
                      Item_func::COND_AND_FUNC;
    if (and_level)
    {
      cond_equal= &((Item_cond_and *) cond)->cond_equal;
      cond_list->disjoin((List<Item> *) &cond_equal->current_level);

      List_iterator_fast<Item_equal> it(cond_equal->current_level);      
unknown's avatar
unknown committed
7042
      while ((item_equal= it++))
7043
      {
unknown's avatar
unknown committed
7044
        item_equal->sort(&compare_fields_by_table_order, table_join_idx);
7045 7046 7047 7048 7049 7050 7051
      }
    }
    
    List_iterator<Item> li(*cond_list);
    Item *item;
    while ((item= li++))
    {
unknown's avatar
unknown committed
7052
      Item *new_item =substitute_for_best_equal_field(item, cond_equal,
7053 7054 7055 7056 7057
                                                      table_join_idx);
      /*
        This works OK with PS/SP re-execution as changes are made to
        the arguments of AND/OR items only
      */
7058 7059
      if (new_item != item)
        li.replace(new_item);
7060
    }
7061 7062 7063 7064

    if (and_level)
    {
      List_iterator_fast<Item_equal> it(cond_equal->current_level);
unknown's avatar
unknown committed
7065
      while ((item_equal= it++))
7066
      {
unknown's avatar
unknown committed
7067
        eliminate_item_equal(cond, cond_equal->upper_levels, item_equal);
7068 7069 7070 7071 7072 7073 7074
      }
    }
  }
  else if (cond->type() == Item::FUNC_ITEM && 
           ((Item_cond*) cond)->functype() == Item_func::MULT_EQUAL_FUNC)
  {
    item_equal= (Item_equal *) cond;
unknown's avatar
unknown committed
7075
    item_equal->sort(&compare_fields_by_table_order, table_join_idx);
unknown's avatar
unknown committed
7076 7077 7078
    if (cond_equal && cond_equal->current_level.head() == item_equal)
      cond_equal= 0;
    return eliminate_item_equal(0, cond_equal, item_equal);
7079 7080
  }
  else
unknown's avatar
unknown committed
7081
    cond->transform(&Item::replace_equal_field, 0);
7082 7083 7084
  return cond;
}

unknown's avatar
unknown committed
7085

unknown's avatar
unknown committed
7086
/*
7087 7088
  change field = field to field = const for each found field = const in the
  and_level
unknown's avatar
unknown committed
7089 7090 7091
*/

static void
7092 7093 7094
change_cond_ref_to_const(THD *thd, I_List<COND_CMP> *save_list,
                         Item *and_father, Item *cond,
                         Item *field, Item *value)
unknown's avatar
unknown committed
7095 7096 7097 7098 7099 7100 7101 7102
{
  if (cond->type() == Item::COND_ITEM)
  {
    bool and_level= ((Item_cond*) cond)->functype() ==
      Item_func::COND_AND_FUNC;
    List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
    Item *item;
    while ((item=li++))
7103
      change_cond_ref_to_const(thd, save_list,and_level ? cond : item, item,
unknown's avatar
unknown committed
7104 7105 7106 7107 7108 7109 7110
			       field, value);
    return;
  }
  if (cond->eq_cmp_result() == Item::COND_OK)
    return;					// Not a boolean function

  Item_bool_func2 *func=  (Item_bool_func2*) cond;
7111 7112 7113
  Item **args= func->arguments();
  Item *left_item=  args[0];
  Item *right_item= args[1];
unknown's avatar
unknown committed
7114 7115
  Item_func::Functype functype=  func->functype();

7116 7117 7118 7119
  if (right_item->eq(field,0) && left_item != value &&
      (left_item->result_type() != STRING_RESULT ||
       value->result_type() != STRING_RESULT ||
       left_item->collation.collation == value->collation.collation))
unknown's avatar
unknown committed
7120 7121 7122 7123
  {
    Item *tmp=value->new_item();
    if (tmp)
    {
7124
      thd->change_item_tree(args + 1, tmp);
unknown's avatar
unknown committed
7125 7126 7127 7128 7129 7130 7131 7132 7133
      func->update_used_tables();
      if ((functype == Item_func::EQ_FUNC || functype == Item_func::EQUAL_FUNC)
	  && and_father != cond && !left_item->const_item())
      {
	cond->marker=1;
	COND_CMP *tmp2;
	if ((tmp2=new COND_CMP(and_father,func)))
	  save_list->push_back(tmp2);
      }
7134
      func->set_cmp_func();
unknown's avatar
unknown committed
7135 7136
    }
  }
7137 7138 7139 7140
  else if (left_item->eq(field,0) && right_item != value &&
           (right_item->result_type() != STRING_RESULT ||
            value->result_type() != STRING_RESULT ||
            right_item->collation.collation == value->collation.collation))
unknown's avatar
unknown committed
7141 7142 7143 7144
  {
    Item *tmp=value->new_item();
    if (tmp)
    {
7145 7146
      thd->change_item_tree(args, tmp);
      value= tmp;
unknown's avatar
unknown committed
7147 7148 7149 7150
      func->update_used_tables();
      if ((functype == Item_func::EQ_FUNC || functype == Item_func::EQUAL_FUNC)
	  && and_father != cond && !right_item->const_item())
      {
7151
        args[0]= args[1];                       // For easy check
7152
        thd->change_item_tree(args + 1, value);
unknown's avatar
unknown committed
7153 7154 7155 7156 7157
	cond->marker=1;
	COND_CMP *tmp2;
	if ((tmp2=new COND_CMP(and_father,func)))
	  save_list->push_back(tmp2);
      }
7158
      func->set_cmp_func();
unknown's avatar
unknown committed
7159 7160 7161 7162
    }
  }
}

7163 7164 7165 7166 7167 7168 7169 7170 7171 7172 7173 7174 7175 7176 7177 7178 7179 7180 7181 7182 7183 7184 7185 7186 7187 7188 7189 7190 7191 7192 7193 7194 7195
/*
  Remove additional condition inserted by IN/ALL/ANY transformation

  SYNOPSIS
    remove_additional_cond()
    conds - condition for processing

  RETURN VALUES
    new conditions
*/

static Item *remove_additional_cond(Item* conds)
{
  if (conds->name == in_additional_cond)
    return 0;
  if (conds->type() == Item::COND_ITEM)
  {
    Item_cond *cnd= (Item_cond*) conds;
    List_iterator<Item> li(*(cnd->argument_list()));
    Item *item;
    while ((item= li++))
    {
      if (item->name == in_additional_cond)
      {
	li.remove();
	if (cnd->argument_list()->elements == 1)
	  return cnd->argument_list()->head();
	return conds;
      }
    }
  }
  return conds;
}
unknown's avatar
unknown committed
7196 7197

static void
7198 7199
propagate_cond_constants(THD *thd, I_List<COND_CMP> *save_list,
                         COND *and_father, COND *cond)
unknown's avatar
unknown committed
7200 7201 7202 7203 7204
{
  if (cond->type() == Item::COND_ITEM)
  {
    bool and_level= ((Item_cond*) cond)->functype() ==
      Item_func::COND_AND_FUNC;
unknown's avatar
unknown committed
7205
    List_iterator_fast<Item> li(*((Item_cond*) cond)->argument_list());
unknown's avatar
unknown committed
7206 7207 7208 7209
    Item *item;
    I_List<COND_CMP> save;
    while ((item=li++))
    {
7210
      propagate_cond_constants(thd, &save,and_level ? cond : item, item);
unknown's avatar
unknown committed
7211 7212 7213 7214 7215 7216
    }
    if (and_level)
    {						// Handle other found items
      I_List_iterator<COND_CMP> cond_itr(save);
      COND_CMP *cond_cmp;
      while ((cond_cmp=cond_itr++))
7217 7218 7219 7220 7221 7222
      {
        Item **args= cond_cmp->cmp_func->arguments();
        if (!args[0]->const_item())
          change_cond_ref_to_const(thd, &save,cond_cmp->and_level,
                                   cond_cmp->and_level, args[0], args[1]);
      }
unknown's avatar
unknown committed
7223 7224
    }
  }
7225
  else if (and_father != cond && !cond->marker)		// In a AND group
unknown's avatar
unknown committed
7226 7227 7228 7229 7230 7231
  {
    if (cond->type() == Item::FUNC_ITEM &&
	(((Item_func*) cond)->functype() == Item_func::EQ_FUNC ||
	 ((Item_func*) cond)->functype() == Item_func::EQUAL_FUNC))
    {
      Item_func_eq *func=(Item_func_eq*) cond;
7232 7233 7234
      Item **args= func->arguments();
      bool left_const= args[0]->const_item();
      bool right_const= args[1]->const_item();
7235
      if (!(left_const && right_const) &&
7236
          args[0]->result_type() == args[1]->result_type())
unknown's avatar
unknown committed
7237 7238 7239
      {
	if (right_const)
	{
7240
          resolve_const_item(thd, &args[1], args[0]);
unknown's avatar
unknown committed
7241
	  func->update_used_tables();
7242 7243
          change_cond_ref_to_const(thd, save_list, and_father, and_father,
                                   args[0], args[1]);
unknown's avatar
unknown committed
7244 7245 7246
	}
	else if (left_const)
	{
7247
          resolve_const_item(thd, &args[0], args[1]);
unknown's avatar
unknown committed
7248
	  func->update_used_tables();
7249 7250
          change_cond_ref_to_const(thd, save_list, and_father, and_father,
                                   args[1], args[0]);
unknown's avatar
unknown committed
7251 7252 7253 7254 7255 7256 7257
	}
      }
    }
  }
}


7258 7259 7260 7261 7262 7263 7264 7265 7266 7267 7268 7269 7270 7271 7272 7273 7274 7275 7276 7277 7278 7279 7280 7281 7282 7283 7284 7285 7286 7287 7288 7289 7290 7291 7292 7293 7294 7295 7296 7297 7298 7299 7300 7301 7302 7303 7304 7305 7306 7307 7308 7309 7310 7311 7312 7313 7314 7315 7316 7317 7318 7319 7320 7321
/*
  Simplify joins replacing outer joins by inner joins whenever it's possible

  SYNOPSIS
    simplify_joins()
    join        reference to the query info
    join_list   list representation of the join to be converted
    conds       conditions to add on expressions for converted joins
    top         true <=> conds is the where condition  

  DESCRIPTION
    The function, during a retrieval of join_list,  eliminates those
    outer joins that can be converted into inner join, possibly nested.
    It also moves the on expressions for the converted outer joins
    and from inner joins to conds.
    The function also calculates some attributes for nested joins:
    - used_tables    
    - not_null_tables
    - dep_tables.
    - on_expr_dep_tables
    The first two attributes are used to test whether an outer join can
    be substituted for an inner join. The third attribute represents the
    relation 'to be dependent on' for tables. If table t2 is dependent
    on table t1, then in any evaluated execution plan table access to
    table t2 must precede access to table t2. This relation is used also
    to check whether the query contains  invalid cross-references.
    The forth attribute is an auxiliary one and is used to calculate
    dep_tables.
    As the attribute dep_tables qualifies possibles orders of tables in the
    execution plan, the dependencies required by the straight join
    modifiers are reflected in this attribute as well.
    The function also removes all braces that can be removed from the join
    expression without changing its meaning.

  NOTES
    An outer join can be replaced by an inner join if the where condition
    or the on expression for an embedding nested join contains a conjunctive
    predicate rejecting null values for some attribute of the inner tables.

    E.g. in the query:    
      SELECT * FROM t1 LEFT JOIN t2 ON t2.a=t1.a WHERE t2.b < 5
    the predicate t2.b < 5 rejects nulls.
    The query is converted first to:
      SELECT * FROM t1 INNER JOIN t2 ON t2.a=t1.a WHERE t2.b < 5
    then to the equivalent form:
      SELECT * FROM t1, t2 ON t2.a=t1.a WHERE t2.b < 5 AND t2.a=t1.a.

    Similarly the following query:
      SELECT * from t1 LEFT JOIN (t2, t3) ON t2.a=t1.a t3.b=t1.b
        WHERE t2.c < 5  
    is converted to:
      SELECT * FROM t1, (t2, t3) WHERE t2.c < 5 AND t2.a=t1.a t3.b=t1.b 

    One conversion might trigger another:
      SELECT * FROM t1 LEFT JOIN t2 ON t2.a=t1.a
                       LEFT JOIN t3 ON t3.b=t2.b
        WHERE t3 IS NOT NULL =>
      SELECT * FROM t1 LEFT JOIN t2 ON t2.a=t1.a, t3
        WHERE t3 IS NOT NULL AND t3.b=t2.b => 
      SELECT * FROM t1, t2, t3
        WHERE t3 IS NOT NULL AND t3.b=t2.b AND t2.a=t1.a
   
    The function removes all unnecessary braces from the expression
    produced by the conversions.
7322
    E.g. SELECT * FROM t1, (t2, t3) WHERE t2.c < 5 AND t2.a=t1.a AND t3.b=t1.b
7323
    finally is converted to: 
7324
      SELECT * FROM t1, t2, t3 WHERE t2.c < 5 AND t2.a=t1.a AND t3.b=t1.b
7325 7326 7327 7328 7329 7330 7331 7332 7333 7334 7335 7336 7337 7338 7339 7340 7341 7342 7343 7344 7345 7346 7347 7348 7349 7350 7351 7352 7353 7354 7355 7356 7357 7358

    It also will remove braces from the following queries:
      SELECT * from (t1 LEFT JOIN t2 ON t2.a=t1.a) LEFT JOIN t3 ON t3.b=t2.b
      SELECT * from (t1, (t2,t3)) WHERE t1.a=t2.a AND t2.b=t3.b.

    The benefit of this simplification procedure is that it might return 
    a query for which the optimizer can evaluate execution plan with more
    join orders. With a left join operation the optimizer does not
    consider any plan where one of the inner tables is before some of outer
    tables.

  IMPLEMENTATION.
    The function is implemented by a recursive procedure.  On the recursive
    ascent all attributes are calculated, all outer joins that can be
    converted are replaced and then all unnecessary braces are removed.
    As join list contains join tables in the reverse order sequential
    elimination of outer joins does not requite extra recursive calls.

  EXAMPLES
    Here is an example of a join query with invalid cross references:
      SELECT * FROM t1 LEFT JOIN t2 ON t2.a=t3.a LEFT JOIN ON  t3.b=t1.b 
     
  RETURN VALUE
    The new condition, if success
    0, otherwise  
*/

static COND *
simplify_joins(JOIN *join, List<TABLE_LIST> *join_list, COND *conds, bool top)
{
  TABLE_LIST *table;
  NESTED_JOIN *nested_join;
  TABLE_LIST *prev_table= 0;
  List_iterator<TABLE_LIST> li(*join_list);
7359
  DBUG_ENTER("simplify_joins");
7360 7361 7362 7363 7364 7365 7366 7367 7368 7369 7370 7371 7372 7373 7374 7375 7376 7377

  /* 
    Try to simplify join operations from join_list.
    The most outer join operation is checked for conversion first. 
  */
  while ((table= li++))
  {
    table_map used_tables;
    table_map not_null_tables= (table_map) 0;

    if ((nested_join= table->nested_join))
    {
      /* 
         If the element of join_list is a nested join apply
         the procedure to its nested join list first.
      */
      if (table->on_expr)
      {
unknown's avatar
unknown committed
7378
        Item *expr= table->prep_on_expr ? table->prep_on_expr : table->on_expr;
7379 7380 7381 7382 7383 7384 7385 7386
        /* 
           If an on expression E is attached to the table, 
           check all null rejected predicates in this expression.
           If such a predicate over an attribute belonging to
           an inner table of an embedded outer join is found,
           the outer join is converted to an inner join and
           the corresponding on expression is added to E. 
	*/ 
unknown's avatar
unknown committed
7387
        expr= simplify_joins(join, &nested_join->join_list,
unknown's avatar
unknown committed
7388
                             expr, FALSE);
7389
        table->prep_on_expr= table->on_expr= expr;
7390 7391 7392 7393 7394 7395 7396 7397 7398
      }
      nested_join->used_tables= (table_map) 0;
      nested_join->not_null_tables=(table_map) 0;
      conds= simplify_joins(join, &nested_join->join_list, conds, top);
      used_tables= nested_join->used_tables;
      not_null_tables= nested_join->not_null_tables;  
    }
    else
    {
unknown's avatar
unknown committed
7399 7400
      if (!(table->prep_on_expr))
        table->prep_on_expr= table->on_expr;
7401 7402 7403 7404 7405 7406 7407 7408 7409 7410
      used_tables= table->table->map;
      if (conds)
        not_null_tables= conds->not_null_tables();
    }
      
    if (table->embedding)
    {
      table->embedding->nested_join->used_tables|= used_tables;
      table->embedding->nested_join->not_null_tables|= not_null_tables;
    }
7411 7412

    if (!table->outer_join || (used_tables & not_null_tables))
7413 7414 7415 7416 7417 7418 7419 7420 7421 7422 7423 7424
    {
      /* 
        For some of the inner tables there are conjunctive predicates
        that reject nulls => the outer join can be replaced by an inner join.
      */
      table->outer_join= 0;
      if (table->on_expr)
      {
        /* Add on expression to the where condition. */
        if (conds)
        {
          conds= and_conds(conds, table->on_expr);
7425
          conds->top_level_item();
7426 7427 7428
          /* conds is always a new item as both cond and on_expr existed */
          DBUG_ASSERT(!conds->fixed);
          conds->fix_fields(join->thd, 0, &conds);
7429 7430 7431
        }
        else
          conds= table->on_expr; 
7432
        table->prep_on_expr= table->on_expr= 0;
7433 7434 7435 7436 7437 7438 7439 7440 7441 7442 7443 7444 7445 7446 7447 7448 7449 7450 7451 7452 7453 7454 7455 7456 7457 7458 7459 7460 7461 7462 7463 7464
      }
    }
    
    if (!top)
      continue;

    /* 
      Only inner tables of non-convertible outer joins
      remain with on_expr.
    */ 
    if (table->on_expr)
    {
      table->dep_tables|= table->on_expr->used_tables(); 
      if (table->embedding)
      {
        table->dep_tables&= ~table->embedding->nested_join->used_tables;   
        /*
           Embedding table depends on tables used
           in embedded on expressions. 
        */
        table->embedding->on_expr_dep_tables|= table->on_expr->used_tables();
      }
      else
        table->dep_tables&= ~table->table->map;
    }

    if (prev_table)
    {
      /* The order of tables is reverse: prev_table follows table */
      if (prev_table->straight)
        prev_table->dep_tables|= used_tables;
      if (prev_table->on_expr)
7465
      {
7466
        prev_table->dep_tables|= table->on_expr_dep_tables;
7467 7468 7469 7470 7471 7472 7473 7474 7475 7476 7477 7478
        table_map prev_used_tables= prev_table->nested_join ?
	                            prev_table->nested_join->used_tables :
	                            prev_table->table->map;
        /* 
          If on expression contains only references to inner tables
          we still make the inner tables dependent on the outer tables.
          It would be enough to set dependency only on one outer table
          for them. Yet this is really a rare case.
	*/  
        if (!(prev_table->on_expr->used_tables() & ~prev_used_tables))
          prev_table->dep_tables|= used_tables;
      }
7479 7480 7481 7482 7483 7484 7485 7486 7487 7488 7489 7490 7491 7492 7493 7494 7495 7496 7497 7498 7499
    }
    prev_table= table;
  }
    
  /* Flatten nested joins that can be flattened. */
  li.rewind();
  while((table= li++))
  {
    nested_join= table->nested_join;
    if (nested_join && !table->on_expr)
    {
      TABLE_LIST *tbl;
      List_iterator<TABLE_LIST> it(nested_join->join_list);
      while ((tbl= it++))
      {
        tbl->embedding= table->embedding;
        tbl->join_list= table->join_list;
      }      
      li.replace(nested_join->join_list);
    }
  }
unknown's avatar
unknown committed
7500
  DBUG_RETURN(conds); 
7501
}
unknown's avatar
unknown committed
7502
        
unknown's avatar
unknown committed
7503

unknown's avatar
unknown committed
7504
static COND *
unknown's avatar
unknown committed
7505 7506
optimize_cond(JOIN *join, COND *conds, List<TABLE_LIST> *join_list,
              Item::cond_result *cond_value)
unknown's avatar
unknown committed
7507
{
unknown's avatar
unknown committed
7508
  THD *thd= join->thd;
unknown's avatar
unknown committed
7509
  SELECT_LEX *select= thd->lex->current_select;    
7510 7511
  DBUG_ENTER("optimize_cond");

unknown's avatar
unknown committed
7512 7513
  if (!conds)
    *cond_value= Item::COND_TRUE;
7514 7515
  else
  {
unknown's avatar
unknown committed
7516 7517 7518 7519 7520 7521 7522 7523
    /* 
      Build all multiple equality predicates and eliminate equality
      predicates that can be inferred from these multiple equalities.
      For each reference of a field included into a multiple equality
      that occurs in a function set a pointer to the multiple equality
      predicate. Substitute a constant instead of this field if the
      multiple equality contains a constant.
    */ 
7524
    DBUG_EXECUTE("where", print_where(conds, "original"););
unknown's avatar
unknown committed
7525 7526 7527 7528
    conds= build_equal_items(join->thd, conds, NULL, join_list,
                             &join->cond_equal);
    DBUG_EXECUTE("where",print_where(conds,"after equal_items"););

7529
    /* change field = field to field = const for each found field = const */
7530
    propagate_cond_constants(thd, (I_List<COND_CMP> *) 0, conds, conds);
7531 7532 7533 7534 7535 7536 7537
    /*
      Remove all instances of item == item
      Remove all and-levels where CONST item != CONST item
    */
    DBUG_EXECUTE("where",print_where(conds,"after const change"););
    conds= remove_eq_conds(thd, conds, cond_value) ;
    DBUG_EXECUTE("info",print_where(conds,"after remove"););
unknown's avatar
unknown committed
7538
  }
7539
  DBUG_RETURN(conds);
unknown's avatar
unknown committed
7540 7541 7542 7543
}


/*
7544 7545 7546 7547 7548
  Remove const and eq items. Return new item, or NULL if no condition
  cond_value is set to according:
  COND_OK    query is possible (field = constant)
  COND_TRUE  always true	( 1 = 1 )
  COND_FALSE always false	( 1 = 2 )
unknown's avatar
unknown committed
7549 7550 7551
*/

static COND *
unknown's avatar
af  
unknown committed
7552
remove_eq_conds(THD *thd, COND *cond, Item::cond_result *cond_value)
unknown's avatar
unknown committed
7553 7554 7555 7556 7557 7558 7559
{
  if (cond->type() == Item::COND_ITEM)
  {
    bool and_level= ((Item_cond*) cond)->functype()
      == Item_func::COND_AND_FUNC;
    List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
    Item::cond_result tmp_cond_value;
7560
    bool should_fix_fields=0;
unknown's avatar
unknown committed
7561 7562 7563 7564 7565

    *cond_value=Item::COND_UNDEF;
    Item *item;
    while ((item=li++))
    {
unknown's avatar
af  
unknown committed
7566
      Item *new_item=remove_eq_conds(thd, item, &tmp_cond_value);
unknown's avatar
unknown committed
7567 7568 7569 7570 7571
      if (!new_item)
	li.remove();
      else if (item != new_item)
      {
	VOID(li.replace(new_item));
7572
	should_fix_fields=1;
unknown's avatar
unknown committed
7573 7574 7575 7576 7577 7578 7579 7580 7581 7582 7583 7584 7585 7586 7587 7588 7589 7590 7591 7592 7593 7594 7595 7596 7597 7598
      }
      if (*cond_value == Item::COND_UNDEF)
	*cond_value=tmp_cond_value;
      switch (tmp_cond_value) {
      case Item::COND_OK:			// Not TRUE or FALSE
	if (and_level || *cond_value == Item::COND_FALSE)
	  *cond_value=tmp_cond_value;
	break;
      case Item::COND_FALSE:
	if (and_level)
	{
	  *cond_value=tmp_cond_value;
	  return (COND*) 0;			// Always false
	}
	break;
      case Item::COND_TRUE:
	if (!and_level)
	{
	  *cond_value= tmp_cond_value;
	  return (COND*) 0;			// Always true
	}
	break;
      case Item::COND_UNDEF:			// Impossible
	break; /* purecov: deadcode */
      }
    }
7599
    if (should_fix_fields)
unknown's avatar
af  
unknown committed
7600
      cond->update_used_tables();
7601

unknown's avatar
unknown committed
7602 7603 7604 7605 7606 7607 7608 7609 7610 7611 7612 7613 7614 7615
    if (!((Item_cond*) cond)->argument_list()->elements ||
	*cond_value != Item::COND_OK)
      return (COND*) 0;
    if (((Item_cond*) cond)->argument_list()->elements == 1)
    {						// Remove list
      item= ((Item_cond*) cond)->argument_list()->head();
      ((Item_cond*) cond)->argument_list()->empty();
      return item;
    }
  }
  else if (cond->type() == Item::FUNC_ITEM &&
	   ((Item_func*) cond)->functype() == Item_func::ISNULL_FUNC)
  {
    /*
7616 7617 7618 7619 7620 7621 7622
      Handles this special case for some ODBC applications:
      The are requesting the row that was just updated with a auto_increment
      value with this construct:

      SELECT * from table_name where auto_increment_column IS NULL
      This will be changed to:
      SELECT * from table_name where auto_increment_column = LAST_INSERT_ID
unknown's avatar
unknown committed
7623 7624 7625 7626 7627 7628 7629 7630
    */

    Item_func_isnull *func=(Item_func_isnull*) cond;
    Item **args= func->arguments();
    if (args[0]->type() == Item::FIELD_ITEM)
    {
      Field *field=((Item_field*) args[0])->field;
      if (field->flags & AUTO_INCREMENT_FLAG && !field->table->maybe_null &&
7631 7632
	  (thd->options & OPTION_AUTO_IS_NULL) &&
	  thd->insert_id())
unknown's avatar
unknown committed
7633
      {
7634
#ifdef HAVE_QUERY_CACHE
unknown's avatar
unknown committed
7635
	query_cache_abort(&thd->net);
7636
#endif
unknown's avatar
unknown committed
7637 7638 7639
	COND *new_cond;
	if ((new_cond= new Item_func_eq(args[0],
					new Item_int("last_insert_id()",
7640
						     thd->insert_id(),
unknown's avatar
unknown committed
7641 7642 7643
						     21))))
	{
	  cond=new_cond;
unknown's avatar
unknown committed
7644 7645 7646 7647 7648
          /*
            Item_func_eq can't be fixed after creation so we do not check
            cond->fixed, also it do not need tables so we use 0 as second
            argument.
          */
unknown's avatar
unknown committed
7649
	  cond->fix_fields(thd, 0, &cond);
unknown's avatar
unknown committed
7650
	}
7651
	thd->insert_id(0);		// Clear for next request
unknown's avatar
unknown committed
7652 7653 7654 7655
      }
      /* fix to replace 'NULL' dates with '0' (shreeve@uci.edu) */
      else if (((field->type() == FIELD_TYPE_DATE) ||
		(field->type() == FIELD_TYPE_DATETIME)) &&
7656 7657
		(field->flags & NOT_NULL_FLAG) &&
	       !field->table->maybe_null)
unknown's avatar
unknown committed
7658 7659 7660 7661 7662
      {
	COND *new_cond;
	if ((new_cond= new Item_func_eq(args[0],new Item_int("0", 0, 2))))
	{
	  cond=new_cond;
unknown's avatar
unknown committed
7663 7664 7665 7666 7667
          /*
            Item_func_eq can't be fixed after creation so we do not check
            cond->fixed, also it do not need tables so we use 0 as second
            argument.
          */
unknown's avatar
unknown committed
7668
	  cond->fix_fields(thd, 0, &cond);
unknown's avatar
unknown committed
7669 7670 7671
	}
      }
    }
unknown's avatar
unknown committed
7672 7673 7674 7675 7676
    if (cond->const_item())
    {
      *cond_value= eval_const_cond(cond) ? Item::COND_TRUE : Item::COND_FALSE;
      return (COND*) 0;
    }
unknown's avatar
unknown committed
7677 7678 7679 7680 7681 7682 7683 7684 7685 7686
  }
  else if (cond->const_item())
  {
    *cond_value= eval_const_cond(cond) ? Item::COND_TRUE : Item::COND_FALSE;
    return (COND*) 0;
  }
  else if ((*cond_value= cond->eq_cmp_result()) != Item::COND_OK)
  {						// boolan compare function
    Item *left_item=	((Item_func*) cond)->arguments()[0];
    Item *right_item= ((Item_func*) cond)->arguments()[1];
7687
    if (left_item->eq(right_item,1))
unknown's avatar
unknown committed
7688 7689 7690 7691 7692 7693 7694
    {
      if (!left_item->maybe_null ||
	  ((Item_func*) cond)->functype() == Item_func::EQUAL_FUNC)
	return (COND*) 0;			// Compare of identical items
    }
  }
  *cond_value=Item::COND_OK;
7695
  return cond;					// Point at next and level
unknown's avatar
unknown committed
7696 7697 7698
}

/*
7699
  Return 1 if the item is a const value in all the WHERE clause
unknown's avatar
unknown committed
7700 7701 7702 7703 7704 7705 7706 7707 7708
*/

static bool
const_expression_in_where(COND *cond, Item *comp_item, Item **const_item)
{
  if (cond->type() == Item::COND_ITEM)
  {
    bool and_level= (((Item_cond*) cond)->functype()
		     == Item_func::COND_AND_FUNC);
unknown's avatar
unknown committed
7709
    List_iterator_fast<Item> li(*((Item_cond*) cond)->argument_list());
unknown's avatar
unknown committed
7710 7711 7712 7713 7714 7715 7716 7717 7718 7719 7720 7721 7722 7723 7724 7725 7726 7727 7728 7729 7730 7731
    Item *item;
    while ((item=li++))
    {
      bool res=const_expression_in_where(item, comp_item, const_item);
      if (res)					// Is a const value
      {
	if (and_level)
	  return 1;
      }
      else if (!and_level)
	return 0;
    }
    return and_level ? 0 : 1;
  }
  else if (cond->eq_cmp_result() != Item::COND_OK)
  {						// boolan compare function
    Item_func* func= (Item_func*) cond;
    if (func->functype() != Item_func::EQUAL_FUNC &&
	func->functype() != Item_func::EQ_FUNC)
      return 0;
    Item *left_item=	((Item_func*) cond)->arguments()[0];
    Item *right_item= ((Item_func*) cond)->arguments()[1];
7732
    if (left_item->eq(comp_item,1))
unknown's avatar
unknown committed
7733 7734 7735 7736
    {
      if (right_item->const_item())
      {
	if (*const_item)
7737
	  return right_item->eq(*const_item, 1);
unknown's avatar
unknown committed
7738 7739 7740 7741
	*const_item=right_item;
	return 1;
      }
    }
7742
    else if (right_item->eq(comp_item,1))
unknown's avatar
unknown committed
7743 7744 7745 7746
    {
      if (left_item->const_item())
      {
	if (*const_item)
7747
	  return left_item->eq(*const_item, 1);
unknown's avatar
unknown committed
7748 7749 7750 7751 7752 7753 7754 7755 7756
	*const_item=left_item;
	return 1;
      }
    }
  }
  return 0;
}

/****************************************************************************
unknown's avatar
unknown committed
7757
  Create internal temporary table
unknown's avatar
unknown committed
7758 7759
****************************************************************************/

7760 7761 7762 7763 7764 7765 7766
/*
  Create field for temporary table from given field
  
  SYNOPSIS
    create_tmp_field_from_field()
    thd			Thread handler
    org_field           field from which new field will be created
7767
    name                New field name
7768
    table		Temporary table
7769 7770 7771
    item	        !=NULL if item->result_field should point to new field.
			This is relevant for how fill_record() is going to work:
			If item != NULL then fill_record() will update
7772
			the record in the original table.
7773
			If item == NULL then fill_record() will update
7774
			the temporary table
7775 7776
    convert_blob_length If >0 create a varstring(convert_blob_length) field 
                        instead of blob.
7777 7778 7779 7780 7781

  RETURN
    0			on error
    new_created field
*/
7782

7783
Field* create_tmp_field_from_field(THD *thd, Field* org_field,
unknown's avatar
Merge  
unknown committed
7784 7785
                                   const char *name, TABLE *table,
                                   Item_field *item, uint convert_blob_length)
7786 7787 7788
{
  Field *new_field;

7789
  if (convert_blob_length && (org_field->flags & BLOB_FLAG))
7790 7791
    new_field= new Field_varstring(convert_blob_length,
                                   org_field->maybe_null(),
7792 7793 7794
                                   org_field->field_name, table,
                                   org_field->charset());
  else
unknown's avatar
unknown committed
7795
    new_field= org_field->new_field(thd->mem_root, table);
7796
  if (new_field)
7797
  {
7798 7799
    if (item)
      item->result_field= new_field;
7800
    else
7801
      new_field->field_name= name;
unknown's avatar
unknown committed
7802
    if (org_field->maybe_null() || (item && item->maybe_null))
7803
      new_field->flags&= ~NOT_NULL_FLAG;	// Because of outer join
7804 7805
    if (org_field->type() == MYSQL_TYPE_VAR_STRING ||
        org_field->type() == MYSQL_TYPE_VARCHAR)
7806
      table->s->db_create_options|= HA_OPTION_PACK_RECORD;
7807 7808 7809 7810 7811 7812 7813 7814 7815 7816 7817 7818 7819 7820 7821 7822 7823 7824 7825 7826 7827
  }
  return new_field;
}

/*
  Create field for temporary table using type of given item
  
  SYNOPSIS
    create_tmp_field_from_item()
    thd			Thread handler
    item		Item to create a field for
    table		Temporary table
    copy_func		If set and item is a function, store copy of item
			in this array
    modify_item		1 if item->result_field should point to new item.
			This is relevent for how fill_record() is going to
			work:
			If modify_item is 1 then fill_record() will update
			the record in the original table.
			If modify_item is 0 then fill_record() will update
			the temporary table
7828 7829
    convert_blob_length If >0 create a varstring(convert_blob_length) field 
                        instead of blob.
7830 7831 7832 7833 7834

  RETURN
    0			on error
    new_created field
*/
7835 7836

static Field *create_tmp_field_from_item(THD *thd, Item *item, TABLE *table,
7837 7838
                                         Item ***copy_func, bool modify_item,
                                         uint convert_blob_length)
7839 7840 7841 7842 7843 7844 7845 7846 7847 7848 7849 7850 7851 7852 7853
{
  bool maybe_null=item->maybe_null;
  Field *new_field;
  LINT_INIT(new_field);

  switch (item->result_type()) {
  case REAL_RESULT:
    new_field=new Field_double(item->max_length, maybe_null,
			       item->name, table, item->decimals);
    break;
  case INT_RESULT:
    new_field=new Field_longlong(item->max_length, maybe_null,
				   item->name, table, item->unsigned_flag);
    break;
  case STRING_RESULT:
7854 7855 7856 7857
    if (item->max_length > 255 && convert_blob_length)
      new_field= new Field_varstring(convert_blob_length, maybe_null,
                                     item->name, table,
                                     item->collation.collation);
7858
    else
7859
      new_field= item->make_string_field(table);
7860
    break;
unknown's avatar
unknown committed
7861
  case DECIMAL_RESULT:
unknown's avatar
unknown committed
7862 7863
    new_field= new Field_new_decimal(item->max_length, maybe_null, item->name,
                                     table, item->decimals, item->unsigned_flag);
unknown's avatar
unknown committed
7864 7865 7866
    break;
  case ROW_RESULT:
  default:
7867 7868 7869 7870 7871 7872 7873 7874 7875 7876 7877 7878
    // This case should never be choosen
    DBUG_ASSERT(0);
    new_field= 0; // to satisfy compiler (uninitialized variable)
    break;
  }
  if (copy_func && item->is_result_field())
    *((*copy_func)++) = item;			// Save for copy_funcs
  if (modify_item)
    item->set_result_field(new_field);
  return new_field;
}

7879 7880 7881 7882 7883 7884 7885 7886 7887 7888 7889 7890 7891 7892 7893 7894 7895 7896 7897 7898 7899 7900 7901 7902 7903 7904 7905 7906 7907 7908

/*
  Create field for information schema table

  SYNOPSIS
    create_tmp_field_for_schema()
    thd			Thread handler
    table		Temporary table
    item		Item to create a field for

  RETURN
    0			on error
    new_created field
*/

Field *create_tmp_field_for_schema(THD *thd, Item *item, TABLE *table)
{
  if (item->field_type() == MYSQL_TYPE_VARCHAR)
  {
    if (item->max_length > MAX_FIELD_VARCHARLENGTH /
        item->collation.collation->mbmaxlen)
      return new Field_blob(item->max_length, item->maybe_null,
                            item->name, table, item->collation.collation);
    return new Field_varstring(item->max_length, item->maybe_null, item->name,
                               table, item->collation.collation);
  }
  return item->tmp_table_field_from_field_type(table);
}


unknown's avatar
unknown committed
7909 7910 7911 7912 7913 7914 7915 7916 7917 7918 7919
/*
  Create field for temporary table

  SYNOPSIS
    create_tmp_field()
    thd			Thread handler
    table		Temporary table
    item		Item to create a field for
    type		Type of item (normally item->type)
    copy_func		If set and item is a function, store copy of item
			in this array
7920
    from_field          if field will be created using other field as example,
7921
                        pointer example field will be written here
unknown's avatar
unknown committed
7922 7923 7924 7925 7926 7927 7928 7929
    group		1 if we are going to do a relative group by on result
    modify_item		1 if item->result_field should point to new item.
			This is relevent for how fill_record() is going to
			work:
			If modify_item is 1 then fill_record() will update
			the record in the original table.
			If modify_item is 0 then fill_record() will update
			the temporary table
7930 7931
    convert_blob_length If >0 create a varstring(convert_blob_length) field 
                        instead of blob.
7932

unknown's avatar
unknown committed
7933 7934 7935 7936 7937
  RETURN
    0			on error
    new_created field
*/

unknown's avatar
unknown committed
7938
Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
7939 7940
                        Item ***copy_func, Field **from_field,
                        bool group, bool modify_item, uint convert_blob_length)
unknown's avatar
unknown committed
7941 7942 7943 7944 7945
{
  switch (type) {
  case Item::SUM_FUNC_ITEM:
  {
    Item_sum *item_sum=(Item_sum*) item;
unknown's avatar
unknown committed
7946 7947 7948 7949
    Field *result= item_sum->create_tmp_field(group, table, convert_blob_length);
    if (!result)
      thd->fatal_error();
    return result;
unknown's avatar
unknown committed
7950 7951
  }
  case Item::FIELD_ITEM:
7952
  case Item::DEFAULT_VALUE_ITEM:
unknown's avatar
af  
unknown committed
7953 7954
  {
    Item_field *field= (Item_field*) item;
7955 7956 7957 7958
    return create_tmp_field_from_field(thd, (*from_field= field->field),
                                       item->name, table,
                                       modify_item ? (Item_field*) item : NULL,
                                       convert_blob_length);
unknown's avatar
af  
unknown committed
7959
  }
unknown's avatar
unknown committed
7960 7961 7962 7963
  case Item::FUNC_ITEM:
  case Item::COND_ITEM:
  case Item::FIELD_AVG_ITEM:
  case Item::FIELD_STD_ITEM:
7964
  case Item::SUBSELECT_ITEM:
unknown's avatar
unknown committed
7965
    /* The following can only happen with 'CREATE TABLE ... SELECT' */
unknown's avatar
unknown committed
7966
  case Item::PROC_ITEM:
unknown's avatar
unknown committed
7967 7968
  case Item::INT_ITEM:
  case Item::REAL_ITEM:
unknown's avatar
unknown committed
7969
  case Item::DECIMAL_ITEM:
unknown's avatar
unknown committed
7970 7971
  case Item::STRING_ITEM:
  case Item::REF_ITEM:
7972
  case Item::NULL_ITEM:
7973
  case Item::VARBIN_ITEM:
7974 7975
    return create_tmp_field_from_item(thd, item, table, copy_func, modify_item,
                                      convert_blob_length);
7976
  case Item::TYPE_HOLDER:
7977
    return ((Item_type_holder *)item)->make_field_by_type(table);
unknown's avatar
unknown committed
7978 7979 7980 7981 7982 7983
  default:					// Dosen't have to be stored
    return 0;
  }
}


unknown's avatar
unknown committed
7984 7985 7986 7987 7988 7989 7990
/*
  Create a temp table according to a field list.
  Set distinct if duplicates could be removed
  Given fields field pointers are changed to point at tmp_table
  for send_fields
*/

7991 7992 7993 7994 7995
#define STRING_TOTAL_LENGTH_TO_PACK_ROWS 128
#define AVG_STRING_LENGTH_TO_PACK_ROWS   64
#define RATIO_TO_PACK_ROWS	       2
#define MIN_STRING_LENGTH_TO_PACK_ROWS   10

unknown's avatar
unknown committed
7996 7997 7998
TABLE *
create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
		 ORDER *group, bool distinct, bool save_sum_fields,
7999 8000
		 ulong select_options, ha_rows rows_limit,
		 char *table_alias)
unknown's avatar
unknown committed
8001 8002
{
  TABLE *table;
8003 8004 8005 8006 8007 8008 8009
  uint	i,field_count,null_count,null_pack_length;
  uint  hidden_null_count, hidden_null_pack_length, hidden_field_count;
  uint  blob_count,group_null_items, string_count;
  uint  temp_pool_slot=MY_BIT_NONE;
  ulong reclength, string_total_length;
  bool  using_unique_constraint= 0;
  bool  use_packed_rows= 0;
unknown's avatar
unknown committed
8010
  bool  not_all_columns= !(select_options & TMP_TABLE_ALL_COLUMNS);
unknown's avatar
unknown committed
8011
  char	*tmpname,path[FN_REFLEN];
unknown's avatar
unknown committed
8012 8013
  byte	*pos,*group_buff;
  uchar *null_flags;
8014 8015
  Field **reg_field, **from_field;
  uint *blob_field;
unknown's avatar
unknown committed
8016 8017 8018
  Copy_field *copy=0;
  KEY *keyinfo;
  KEY_PART_INFO *key_part_info;
unknown's avatar
unknown committed
8019
  Item **copy_func;
unknown's avatar
unknown committed
8020
  MI_COLUMNDEF *recinfo;
unknown's avatar
unknown committed
8021
  uint total_uneven_bit_length= 0;
unknown's avatar
unknown committed
8022
  DBUG_ENTER("create_tmp_table");
unknown's avatar
unknown committed
8023
  DBUG_PRINT("enter",("distinct: %d  save_sum_fields: %d  rows_limit: %lu  group: %d",
unknown's avatar
unknown committed
8024
		      (int) distinct, (int) save_sum_fields,
unknown's avatar
unknown committed
8025
		      (ulong) rows_limit,test(group)));
unknown's avatar
unknown committed
8026

8027
  statistic_increment(thd->status_var.created_tmp_tables, &LOCK_status);
8028

8029
  if (use_temp_pool)
unknown's avatar
unknown committed
8030
    temp_pool_slot = bitmap_set_next(&temp_pool);
8031 8032

  if (temp_pool_slot != MY_BIT_NONE) // we got a slot
8033
    sprintf(path, "%s_%lx_%i", tmp_file_prefix,
8034
	    current_pid, temp_pool_slot);
8035 8036 8037
  else
  {
    /* if we run out of slots or we are not using tempool */
8038
    sprintf(path,"%s%lx_%lx_%x", tmp_file_prefix,current_pid,
8039
            thd->thread_id, thd->tmp_table++);
8040
  }
8041

8042
  /*
unknown's avatar
Merge  
unknown committed
8043
    No need to change table name to lower case as we are only creating
8044 8045
    MyISAM or HEAP tables here
  */
8046
  fn_format(path, path, mysql_tmpdir, "", MY_REPLACE_EXT|MY_UNPACK_FILENAME);
8047

unknown's avatar
unknown committed
8048 8049 8050 8051 8052
  if (group)
  {
    if (!param->quick_group)
      group=0;					// Can't use group key
    else for (ORDER *tmp=group ; tmp ; tmp=tmp->next)
8053
    {
unknown's avatar
unknown committed
8054
      (*tmp->item)->marker=4;			// Store null in key
8055
      if ((*tmp->item)->max_length >= CONVERT_IF_BIGGER_TO_BLOB)
8056 8057
	using_unique_constraint=1;
    }
unknown's avatar
unknown committed
8058 8059
    if (param->group_length >= MAX_BLOB_WIDTH)
      using_unique_constraint=1;
unknown's avatar
unknown committed
8060 8061
    if (group)
      distinct=0;				// Can't use distinct
unknown's avatar
unknown committed
8062 8063 8064
  }

  field_count=param->field_count+param->func_count+param->sum_func_count;
unknown's avatar
unknown committed
8065
  hidden_field_count=param->hidden_field_count;
unknown's avatar
unknown committed
8066 8067
  if (!my_multi_malloc(MYF(MY_WME),
		       &table,sizeof(*table),
8068
		       &reg_field,  sizeof(Field*)*(field_count+1),
8069
		       &blob_field, sizeof(uint)*(field_count+1),
8070
		       &from_field, sizeof(Field*)*field_count,
unknown's avatar
unknown committed
8071 8072 8073 8074 8075 8076 8077 8078 8079 8080 8081
		       &copy_func,sizeof(*copy_func)*(param->func_count+1),
		       &param->keyinfo,sizeof(*param->keyinfo),
		       &key_part_info,
		       sizeof(*key_part_info)*(param->group_parts+1),
		       &param->start_recinfo,
		       sizeof(*param->recinfo)*(field_count*2+4),
		       &tmpname,(uint) strlen(path)+1,
		       &group_buff,group && ! using_unique_constraint ?
		       param->group_length : 0,
		       NullS))
  {
unknown's avatar
unknown committed
8082
    bitmap_clear_bit(&temp_pool, temp_pool_slot);
8083
    DBUG_RETURN(NULL);				/* purecov: inspected */
unknown's avatar
unknown committed
8084 8085 8086
  }
  if (!(param->copy_field=copy=new Copy_field[field_count]))
  {
unknown's avatar
unknown committed
8087
    bitmap_clear_bit(&temp_pool, temp_pool_slot);
8088 8089
    my_free((gptr) table,MYF(0));		/* purecov: inspected */
    DBUG_RETURN(NULL);				/* purecov: inspected */
unknown's avatar
unknown committed
8090
  }
unknown's avatar
unknown committed
8091
  param->items_to_copy= copy_func;
unknown's avatar
unknown committed
8092 8093 8094 8095 8096 8097 8098
  strmov(tmpname,path);
  /* make table according to fields */

  bzero((char*) table,sizeof(*table));
  bzero((char*) reg_field,sizeof(Field*)*(field_count+1));
  bzero((char*) from_field,sizeof(Field*)*field_count);
  table->field=reg_field;
8099
  table->alias= table_alias;
unknown's avatar
unknown committed
8100 8101 8102
  table->reginfo.lock_type=TL_WRITE;	/* Will be updated */
  table->db_stat=HA_OPEN_KEYFILE+HA_OPEN_RNDFILE;
  table->map=1;
8103
  table->temp_pool_slot = temp_pool_slot;
8104
  table->copy_blobs= 1;
8105
  table->in_use= thd;
8106 8107 8108
  table->quick_keys.init();
  table->used_keys.init();
  table->keys_in_use_for_query.init();
unknown's avatar
unknown committed
8109

8110 8111 8112 8113 8114 8115 8116 8117 8118 8119 8120
  table->s= &table->share_not_to_be_used;
  table->s->blob_field= blob_field;
  table->s->table_name= table->s->path= tmpname;
  table->s->db= "";
  table->s->blob_ptr_size= mi_portable_sizeof_char_ptr;
  table->s->tmp_table= TMP_TABLE;
  table->s->db_low_byte_first=1;                // True for HEAP and MyISAM
  table->s->table_charset= param->table_charset;
  table->s->keys_for_keyread.init();
  table->s->keys_in_use.init();
  /* For easier error reporting */
unknown's avatar
unknown committed
8121
  table->s->table_cache_key= (char*) (table->s->db= "");
8122 8123


unknown's avatar
unknown committed
8124
  /* Calculate which type of fields we will store in the temporary table */
unknown's avatar
unknown committed
8125

8126 8127
  reclength= string_total_length= 0;
  blob_count= string_count= null_count= hidden_null_count= group_null_items= 0;
unknown's avatar
unknown committed
8128
  param->using_indirect_summary_function=0;
unknown's avatar
unknown committed
8129

unknown's avatar
unknown committed
8130
  List_iterator_fast<Item> li(fields);
unknown's avatar
unknown committed
8131 8132
  Item *item;
  Field **tmp_from_field=from_field;
8133
  while ((item=li++))
unknown's avatar
unknown committed
8134 8135
  {
    Item::Type type=item->type();
unknown's avatar
unknown committed
8136
    if (not_all_columns)
unknown's avatar
unknown committed
8137
    {
unknown's avatar
unknown committed
8138 8139 8140 8141 8142 8143 8144 8145 8146 8147
      if (item->with_sum_func && type != Item::SUM_FUNC_ITEM)
      {
	/*
	  Mark that the we have ignored an item that refers to a summary
	  function. We need to know this if someone is going to use
	  DISTINCT on the result.
	*/
	param->using_indirect_summary_function=1;
	continue;
      }
8148
      if (item->const_item() && (int) hidden_field_count <= 0)
8149
        continue; // We don't have to store this
unknown's avatar
unknown committed
8150
    }
unknown's avatar
unknown committed
8151 8152 8153 8154 8155
    if (type == Item::SUM_FUNC_ITEM && !group && !save_sum_fields)
    {						/* Can't calc group yet */
      ((Item_sum*) item)->result_field=0;
      for (i=0 ; i < ((Item_sum*) item)->arg_count ; i++)
      {
8156 8157
	Item **argp= ((Item_sum*) item)->args + i;
	Item *arg= *argp;
unknown's avatar
unknown committed
8158 8159 8160
	if (!arg->const_item())
	{
	  Field *new_field=
8161 8162 8163
            create_tmp_field(thd, table, arg, arg->type(), &copy_func,
                             tmp_from_field, group != 0,not_all_columns,
                             param->convert_blob_length);
unknown's avatar
unknown committed
8164 8165 8166 8167 8168
	  if (!new_field)
	    goto err;					// Should be OOM
	  tmp_from_field++;
	  reclength+=new_field->pack_length();
	  if (new_field->flags & BLOB_FLAG)
8169
	  {
8170
	    *blob_field++= (uint) (reg_field - table->field);
unknown's avatar
unknown committed
8171
	    blob_count++;
8172
	  }
8173
	  *(reg_field++)= new_field;
8174 8175 8176 8177 8178 8179
          if (new_field->real_type() == MYSQL_TYPE_STRING ||
              new_field->real_type() == MYSQL_TYPE_VARCHAR)
          {
            string_count++;
            string_total_length+= new_field->pack_length();
          }
8180
          thd->change_item_tree(argp, new Item_field(new_field));
8181 8182 8183 8184 8185 8186 8187
	  if (!(new_field->flags & NOT_NULL_FLAG))
          {
	    null_count++;
            /*
              new_field->maybe_null() is still false, it will be
              changed below. But we have to setup Item_field correctly
            */
8188
            (*argp)->maybe_null=1;
8189
          }
8190
          new_field->query_id= thd->query_id;
unknown's avatar
unknown committed
8191 8192 8193 8194 8195
	}
      }
    }
    else
    {
unknown's avatar
unknown committed
8196 8197 8198 8199 8200 8201 8202 8203 8204 8205
      /*
	The last parameter to create_tmp_field() is a bit tricky:

	We need to set it to 0 in union, to get fill_record() to modify the
	temporary table.
	We need to set it to 1 on multi-table-update and in select to
	write rows to the temporary table.
	We here distinguish between UNION and multi-table-updates by the fact
	that in the later case group is set to the row pointer.
      */
8206 8207 8208 8209 8210 8211 8212
      Field *new_field= (param->schema_table) ?
        create_tmp_field_for_schema(thd, item, table) :
        create_tmp_field(thd, table, item, type, &copy_func,
                         tmp_from_field, group != 0,
                         not_all_columns || group !=0,
                         param->convert_blob_length);

unknown's avatar
unknown committed
8213 8214
      if (!new_field)
      {
8215
	if (thd->is_fatal_error)
unknown's avatar
unknown committed
8216 8217 8218 8219 8220 8221 8222 8223 8224
	  goto err;				// Got OOM
	continue;				// Some kindf of const item
      }
      if (type == Item::SUM_FUNC_ITEM)
	((Item_sum *) item)->result_field= new_field;
      tmp_from_field++;
      reclength+=new_field->pack_length();
      if (!(new_field->flags & NOT_NULL_FLAG))
	null_count++;
unknown's avatar
unknown committed
8225 8226
      if (new_field->type() == FIELD_TYPE_BIT)
        total_uneven_bit_length+= new_field->field_length & 7;
unknown's avatar
unknown committed
8227
      if (new_field->flags & BLOB_FLAG)
8228
      {
8229
        *blob_field++= (uint) (reg_field - table->field);
unknown's avatar
unknown committed
8230
	blob_count++;
8231
      }
unknown's avatar
unknown committed
8232 8233 8234 8235 8236
      if (item->marker == 4 && item->maybe_null)
      {
	group_null_items++;
	new_field->flags|= GROUP_FLAG;
      }
8237
      new_field->query_id= thd->query_id;
unknown's avatar
unknown committed
8238 8239
      *(reg_field++) =new_field;
    }
unknown's avatar
unknown committed
8240 8241
    if (!--hidden_field_count)
      hidden_null_count=null_count;
unknown's avatar
unknown committed
8242
  }
8243
  DBUG_ASSERT(field_count >= (uint) (reg_field - table->field));
unknown's avatar
unknown committed
8244
  field_count= (uint) (reg_field - table->field);
8245
  *blob_field= 0;				// End marker
unknown's avatar
unknown committed
8246 8247

  /* If result table is small; use a heap */
8248
  if (blob_count || using_unique_constraint ||
unknown's avatar
unknown committed
8249 8250 8251
      (select_options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) ==
      OPTION_BIG_TABLES)
  {
8252
    table->file=get_new_handler(table,table->s->db_type= DB_TYPE_MYISAM);
unknown's avatar
unknown committed
8253 8254 8255 8256 8257 8258 8259
    if (group &&
	(param->group_parts > table->file->max_key_parts() ||
	 param->group_length > table->file->max_key_length()))
      using_unique_constraint=1;
  }
  else
  {
8260
    table->file=get_new_handler(table,table->s->db_type= DB_TYPE_HEAP);
unknown's avatar
unknown committed
8261 8262 8263 8264 8265
  }

  if (!using_unique_constraint)
    reclength+= group_null_items;	// null flag is stored separately

8266
  table->s->blob_fields= blob_count;
unknown's avatar
unknown committed
8267
  if (blob_count == 0)
unknown's avatar
unknown committed
8268 8269
  {
    /* We need to ensure that first byte is not 0 for the delete link */
8270
    if (param->hidden_field_count)
unknown's avatar
unknown committed
8271 8272 8273 8274 8275
      hidden_null_count++;
    else
      null_count++;
  }
  hidden_null_pack_length=(hidden_null_count+7)/8;
unknown's avatar
unknown committed
8276 8277
  null_pack_length= hidden_null_count +
                    (null_count + total_uneven_bit_length + 7) / 8;
unknown's avatar
unknown committed
8278
  reclength+=null_pack_length;
unknown's avatar
unknown committed
8279 8280
  if (!reclength)
    reclength=1;				// Dummy select
8281 8282 8283 8284 8285 8286
  /* Use packed rows if there is blobs or a lot of space to gain */
  if (blob_count ||
      string_total_length >= STRING_TOTAL_LENGTH_TO_PACK_ROWS &&
      (reclength / string_total_length <= RATIO_TO_PACK_ROWS ||
       string_total_length / string_count >= AVG_STRING_LENGTH_TO_PACK_ROWS))
    use_packed_rows= 1;
unknown's avatar
unknown committed
8287

8288 8289
  table->s->fields= field_count;
  table->s->reclength= reclength;
unknown's avatar
unknown committed
8290 8291
  {
    uint alloc_length=ALIGN_SIZE(reclength+MI_UNIQUE_HASH_LENGTH+1);
8292
    table->s->rec_buff_length= alloc_length;
unknown's avatar
unknown committed
8293
    if (!(table->record[0]= (byte *) my_malloc(alloc_length*3, MYF(MY_WME))))
unknown's avatar
unknown committed
8294
      goto err;
unknown's avatar
unknown committed
8295
    table->record[1]= table->record[0]+alloc_length;
8296
    table->s->default_values= table->record[1]+alloc_length;
unknown's avatar
unknown committed
8297 8298 8299 8300 8301 8302 8303 8304 8305 8306 8307 8308 8309
  }
  copy_func[0]=0;				// End marker

  recinfo=param->start_recinfo;
  null_flags=(uchar*) table->record[0];
  pos=table->record[0]+ null_pack_length;
  if (null_pack_length)
  {
    bzero((byte*) recinfo,sizeof(*recinfo));
    recinfo->type=FIELD_NORMAL;
    recinfo->length=null_pack_length;
    recinfo++;
    bfill(null_flags,null_pack_length,255);	// Set null fields
8310 8311

    table->null_flags= (uchar*) table->record[0];
8312 8313
    table->s->null_fields= null_count+ hidden_null_count;
    table->s->null_bytes= null_pack_length;
unknown's avatar
unknown committed
8314 8315
  }
  null_count= (blob_count == 0) ? 1 : 0;
unknown's avatar
unknown committed
8316
  hidden_field_count=param->hidden_field_count;
unknown's avatar
unknown committed
8317 8318 8319 8320 8321 8322 8323 8324 8325 8326
  for (i=0,reg_field=table->field; i < field_count; i++,reg_field++,recinfo++)
  {
    Field *field= *reg_field;
    uint length;
    bzero((byte*) recinfo,sizeof(*recinfo));

    if (!(field->flags & NOT_NULL_FLAG))
    {
      if (field->flags & GROUP_FLAG && !using_unique_constraint)
      {
8327 8328 8329 8330
	/*
	  We have to reserve one byte here for NULL bits,
	  as this is updated by 'end_update()'
	*/
unknown's avatar
unknown committed
8331 8332 8333 8334 8335 8336 8337 8338 8339 8340 8341 8342 8343 8344 8345 8346 8347 8348 8349 8350 8351 8352 8353 8354 8355 8356 8357 8358 8359 8360
	*pos++=0;				// Null is stored here
	recinfo->length=1;
	recinfo->type=FIELD_NORMAL;
	recinfo++;
	bzero((byte*) recinfo,sizeof(*recinfo));
      }
      else
      {
	recinfo->null_bit= 1 << (null_count & 7);
	recinfo->null_pos= null_count/8;
      }
      field->move_field((char*) pos,null_flags+null_count/8,
			1 << (null_count & 7));
      null_count++;
    }
    else
      field->move_field((char*) pos,(uchar*) 0,0);
    field->reset();
    if (from_field[i])
    {						/* Not a table Item */
      copy->set(field,from_field[i],save_sum_fields);
      copy++;
    }
    length=field->pack_length();
    pos+= length;

    /* Make entry for create table */
    recinfo->length=length;
    if (field->flags & BLOB_FLAG)
      recinfo->type= (int) FIELD_BLOB;
8361 8362 8363
    else if (use_packed_rows &&
             field->real_type() == MYSQL_TYPE_STRING &&
	     length >= MIN_STRING_LENGTH_TO_PACK_ROWS)
unknown's avatar
unknown committed
8364
      recinfo->type=FIELD_SKIP_ENDSPACE;
unknown's avatar
unknown committed
8365 8366
    else
      recinfo->type=FIELD_NORMAL;
unknown's avatar
unknown committed
8367 8368
    if (!--hidden_field_count)
      null_count=(null_count+7) & ~7;		// move to next byte
8369 8370

    // fix table name in field entry
8371
    field->table_name= &table->alias;
unknown's avatar
unknown committed
8372 8373
  }

unknown's avatar
unknown committed
8374
  param->copy_field_end=copy;
unknown's avatar
unknown committed
8375
  param->recinfo=recinfo;
8376
  store_record(table,s->default_values);        // Make empty default record
unknown's avatar
unknown committed
8377

8378
  if (thd->variables.tmp_table_size == ~(ulong) 0)		// No limit
8379
    table->s->max_rows= ~(ha_rows) 0;
8380
  else
8381 8382 8383 8384 8385 8386
    table->s->max_rows= (((table->s->db_type == DB_TYPE_HEAP) ?
                          min(thd->variables.tmp_table_size,
                              thd->variables.max_heap_table_size) :
                          thd->variables.tmp_table_size)/ table->s->reclength);
  set_if_bigger(table->s->max_rows,1);		// For dummy start options
  keyinfo= param->keyinfo;
unknown's avatar
unknown committed
8387 8388 8389 8390 8391 8392

  if (group)
  {
    DBUG_PRINT("info",("Creating group key in temporary table"));
    table->group=group;				/* Table is grouped by key */
    param->group_buff=group_buff;
8393 8394
    table->s->keys=1;
    table->s->uniques= test(using_unique_constraint);
unknown's avatar
unknown committed
8395 8396 8397 8398 8399 8400
    table->key_info=keyinfo;
    keyinfo->key_part=key_part_info;
    keyinfo->flags=HA_NOSAME;
    keyinfo->usable_key_parts=keyinfo->key_parts= param->group_parts;
    keyinfo->key_length=0;
    keyinfo->rec_per_key=0;
8401
    keyinfo->algorithm= HA_KEY_ALG_UNDEF;
unknown's avatar
unknown committed
8402
    keyinfo->name= (char*) "group_key";
unknown's avatar
unknown committed
8403 8404
    for (; group ; group=group->next,key_part_info++)
    {
8405
      Field *field=(*group->item)->get_tmp_table_field();
unknown's avatar
unknown committed
8406
      bool maybe_null=(*group->item)->maybe_null;
8407
      key_part_info->null_bit=0;
unknown's avatar
unknown committed
8408 8409
      key_part_info->field=  field;
      key_part_info->offset= field->offset();
8410
      key_part_info->length= (uint16) field->key_length();
unknown's avatar
unknown committed
8411 8412 8413
      key_part_info->type=   (uint8) field->key_type();
      key_part_info->key_type =
	((ha_base_keytype) key_part_info->type == HA_KEYTYPE_TEXT ||
8414 8415
	 (ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT1 ||
	 (ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT2) ?
unknown's avatar
unknown committed
8416 8417 8418 8419
	0 : FIELDFLAG_BINARY;
      if (!using_unique_constraint)
      {
	group->buff=(char*) group_buff;
unknown's avatar
unknown committed
8420 8421 8422 8423 8424
	if (!(group->field= field->new_key_field(thd->mem_root,table,
                                                 (char*) group_buff +
                                                 test(maybe_null),
                                                 field->null_ptr,
                                                 field->null_bit)))
unknown's avatar
unknown committed
8425 8426 8427 8428
	  goto err; /* purecov: inspected */
	if (maybe_null)
	{
	  /*
unknown's avatar
unknown committed
8429 8430
	    To be able to group on NULL, we reserved place in group_buff
	    for the NULL flag just before the column. (see above).
8431
	    The field data is after this flag.
unknown's avatar
unknown committed
8432
	    The NULL flag is updated in 'end_update()' and 'end_write()'
unknown's avatar
unknown committed
8433
	  */
8434 8435 8436 8437
	  keyinfo->flags|= HA_NULL_ARE_EQUAL;	// def. that NULL == NULL
	  key_part_info->null_bit=field->null_bit;
	  key_part_info->null_offset= (uint) (field->null_ptr -
					      (uchar*) table->record[0]);
unknown's avatar
unknown committed
8438 8439
          group->buff++;                        // Pointer to field data
	  group_buff++;                         // Skipp null flag
unknown's avatar
unknown committed
8440
	}
8441 8442
        /* In GROUP BY 'a' and 'a ' are equal for VARCHAR fields */
        key_part_info->key_part_flag|= HA_END_SPACE_ARE_EQUAL;
8443
	group_buff+= group->field->pack_length();
unknown's avatar
unknown committed
8444 8445 8446 8447 8448
      }
      keyinfo->key_length+=  key_part_info->length;
    }
  }

unknown's avatar
unknown committed
8449
  if (distinct)
unknown's avatar
unknown committed
8450
  {
unknown's avatar
unknown committed
8451 8452 8453 8454 8455 8456
    /*
      Create an unique key or an unique constraint over all columns
      that should be in the result.  In the temporary table, there are
      'param->hidden_field_count' extra columns, whose null bits are stored
      in the first 'hidden_null_pack_length' bytes of the row.
    */
8457 8458
    DBUG_PRINT("info",("hidden_field_count: %d", param->hidden_field_count));

unknown's avatar
unknown committed
8459
    null_pack_length-=hidden_null_pack_length;
unknown's avatar
unknown committed
8460
    keyinfo->key_parts= ((field_count-param->hidden_field_count)+
8461
			 test(null_pack_length));
8462
    set_if_smaller(table->s->max_rows, rows_limit);
unknown's avatar
unknown committed
8463
    param->end_write_records= rows_limit;
8464 8465
    table->distinct= 1;
    table->s->keys= 1;
unknown's avatar
unknown committed
8466 8467 8468
    if (blob_count)
    {
      using_unique_constraint=1;
8469
      table->s->uniques= 1;
unknown's avatar
unknown committed
8470 8471 8472 8473 8474 8475
    }
    if (!(key_part_info= (KEY_PART_INFO*)
	  sql_calloc((keyinfo->key_parts)*sizeof(KEY_PART_INFO))))
      goto err;
    table->key_info=keyinfo;
    keyinfo->key_part=key_part_info;
8476
    keyinfo->flags=HA_NOSAME | HA_NULL_ARE_EQUAL;
unknown's avatar
unknown committed
8477
    keyinfo->key_length=(uint16) reclength;
unknown's avatar
unknown committed
8478
    keyinfo->name= (char*) "distinct_key";
8479
    keyinfo->algorithm= HA_KEY_ALG_UNDEF;
8480
    keyinfo->rec_per_key=0;
unknown's avatar
unknown committed
8481
    if (null_pack_length)
unknown's avatar
unknown committed
8482
    {
8483
      key_part_info->null_bit=0;
unknown's avatar
unknown committed
8484 8485
      key_part_info->offset=hidden_null_pack_length;
      key_part_info->length=null_pack_length;
unknown's avatar
unknown committed
8486 8487 8488 8489 8490
      key_part_info->field=new Field_string((char*) table->record[0],
					    (uint32) key_part_info->length,
					    (uchar*) 0,
					    (uint) 0,
					    Field::NONE,
unknown's avatar
unknown committed
8491
					    NullS, table, &my_charset_bin);
unknown's avatar
unknown committed
8492 8493 8494 8495
      key_part_info->key_type=FIELDFLAG_BINARY;
      key_part_info->type=    HA_KEYTYPE_BINARY;
      key_part_info++;
    }
8496
    /* Create a distinct key over the columns we are going to return */
unknown's avatar
unknown committed
8497 8498
    for (i=param->hidden_field_count, reg_field=table->field + i ;
	 i < field_count;
unknown's avatar
unknown committed
8499 8500
	 i++, reg_field++, key_part_info++)
    {
8501
      key_part_info->null_bit=0;
unknown's avatar
unknown committed
8502 8503 8504 8505 8506 8507
      key_part_info->field=    *reg_field;
      key_part_info->offset=   (*reg_field)->offset();
      key_part_info->length=   (uint16) (*reg_field)->pack_length();
      key_part_info->type=     (uint8) (*reg_field)->key_type();
      key_part_info->key_type =
	((ha_base_keytype) key_part_info->type == HA_KEYTYPE_TEXT ||
8508 8509
	 (ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT1 ||
	 (ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT2) ?
unknown's avatar
unknown committed
8510 8511 8512
	0 : FIELDFLAG_BINARY;
    }
  }
8513
  if (thd->is_fatal_error)				// If end of memory
unknown's avatar
unknown committed
8514
    goto err;					 /* purecov: inspected */
8515 8516
  table->s->db_record_offset= 1;
  if (table->s->db_type == DB_TYPE_MYISAM)
unknown's avatar
unknown committed
8517 8518 8519 8520 8521 8522 8523 8524
  {
    if (create_myisam_tmp_table(table,param,select_options))
      goto err;
  }
  if (!open_tmp_table(table))
    DBUG_RETURN(table);

 err:
8525
  free_tmp_table(thd,table);                    /* purecov: inspected */
unknown's avatar
unknown committed
8526
  bitmap_clear_bit(&temp_pool, temp_pool_slot);
unknown's avatar
unknown committed
8527 8528 8529 8530
  DBUG_RETURN(NULL);				/* purecov: inspected */
}


8531 8532 8533 8534 8535 8536 8537 8538 8539 8540 8541 8542 8543 8544 8545 8546 8547 8548 8549 8550 8551 8552 8553 8554 8555 8556 8557 8558 8559 8560 8561 8562 8563 8564 8565 8566 8567 8568 8569 8570 8571 8572 8573 8574 8575 8576 8577 8578 8579 8580 8581 8582 8583 8584 8585 8586 8587 8588 8589 8590 8591 8592 8593 8594 8595 8596 8597 8598 8599 8600 8601 8602 8603 8604 8605 8606 8607 8608 8609 8610 8611 8612 8613 8614 8615 8616 8617 8618 8619 8620 8621 8622 8623 8624 8625 8626 8627 8628 8629 8630 8631 8632 8633 8634 8635 8636 8637 8638 8639 8640 8641
/****************************************************************************/

/*
  Create a reduced TABLE object with properly set up Field list from a
  list of field definitions.

  SYNOPSIS
    create_virtual_tmp_table()
      thd         connection handle
      field_list  list of column definitions

  DESCRIPTION
    The created table doesn't have a table handler assotiated with
    it, has no keys, no group/distinct, no copy_funcs array.
    The sole purpose of this TABLE object is to use the power of Field
    class to read/write data to/from table->record[0]. Then one can store
    the record in any container (RB tree, hash, etc).
    The table is created in THD mem_root, so are the table's fields.
    Consequently, if you don't BLOB fields, you don't need to free it.

  RETURN
    0 if out of memory, TABLE object in case of success
*/

TABLE *create_virtual_tmp_table(THD *thd, List<create_field> &field_list)
{
  uint field_count= field_list.elements;
  Field **field;
  create_field *cdef;                           /* column definition */
  uint record_length= 0;
  uint null_count= 0;                 /* number of columns which may be null */
  uint null_pack_length;              /* NULL representation array length */
  TABLE_SHARE *s;
  /* Create the table and list of all fields */
  TABLE *table= (TABLE*) thd->calloc(sizeof(*table));
  field= (Field**) thd->alloc((field_count + 1) * sizeof(Field*));
  if (!table || !field)
    return 0;

  table->field= field;
  table->s= s= &table->share_not_to_be_used;
  s->fields= field_count;

  /* Create all fields and calculate the total length of record */
  List_iterator_fast<create_field> it(field_list);
  while ((cdef= it++))
  {
    *field= make_field(0, cdef->length,
                       (uchar*) (f_maybe_null(cdef->pack_flag) ? "" : 0),
                       f_maybe_null(cdef->pack_flag) ? 1 : 0,
                       cdef->pack_flag, cdef->sql_type, cdef->charset,
                       cdef->geom_type, cdef->unireg_check,
                       cdef->interval, cdef->field_name, table);
    if (!*field)
      goto error;
    record_length+= (**field).pack_length();
    if (! ((**field).flags & NOT_NULL_FLAG))
      ++null_count;
    ++field;
  }
  *field= NULL;                                 /* mark the end of the list */

  null_pack_length= (null_count + 7)/8;
  s->reclength= record_length + null_pack_length;
  s->rec_buff_length= ALIGN_SIZE(s->reclength + 1);
  table->record[0]= (byte*) thd->alloc(s->rec_buff_length);
  if (!table->record[0])
    goto error;

  if (null_pack_length)
  {
    table->null_flags= (uchar*) table->record[0];
    s->null_fields= null_count;
    s->null_bytes= null_pack_length;
  }

  table->in_use= thd;           /* field->reset() may access table->in_use */
  {
    /* Set up field pointers */
    byte *null_pos= table->record[0];
    byte *field_pos= null_pos + s->null_bytes;
    uint null_bit= 1;

    for (field= table->field; *field; ++field)
    {
      Field *cur_field= *field;
      if ((cur_field->flags & NOT_NULL_FLAG))
        cur_field->move_field((char*) field_pos);
      else
      {
        cur_field->move_field((char*) field_pos, (uchar*) null_pos, null_bit);
        null_bit<<= 1;
        if (null_bit == (1 << 8))
        {
          ++null_pos;
          null_bit= 1;
        }
      }
      cur_field->reset();

      field_pos+= cur_field->pack_length();
    }
  }
  return table;
error:
  for (field= table->field; *field; ++field)
    delete *field;                         /* just invokes field destructor */
  return 0;
}


unknown's avatar
unknown committed
8642 8643 8644
static bool open_tmp_table(TABLE *table)
{
  int error;
8645 8646
  if ((error=table->file->ha_open(table->s->table_name,O_RDWR,
                                  HA_OPEN_TMP_TABLE)))
unknown's avatar
unknown committed
8647 8648 8649 8650 8651 8652 8653 8654 8655 8656 8657
  {
    table->file->print_error(error,MYF(0)); /* purecov: inspected */
    table->db_stat=0;
    return(1);
  }
  (void) table->file->extra(HA_EXTRA_QUICK);		/* Faster */
  return(0);
}


static bool create_myisam_tmp_table(TABLE *table,TMP_TABLE_PARAM *param,
8658
				    ulong options)
unknown's avatar
unknown committed
8659 8660 8661 8662 8663 8664
{
  int error;
  MI_KEYDEF keydef;
  MI_UNIQUEDEF uniquedef;
  KEY *keyinfo=param->keyinfo;
  DBUG_ENTER("create_myisam_tmp_table");
8665

8666
  if (table->s->keys)
unknown's avatar
unknown committed
8667 8668
  {						// Get keys for ni_create
    bool using_unique_constraint=0;
unknown's avatar
unknown committed
8669
    HA_KEYSEG *seg= (HA_KEYSEG*) sql_calloc(sizeof(*seg) *
unknown's avatar
unknown committed
8670 8671 8672 8673 8674 8675
					    keyinfo->key_parts);
    if (!seg)
      goto err;

    if (keyinfo->key_length >= table->file->max_key_length() ||
	keyinfo->key_parts > table->file->max_key_parts() ||
8676
	table->s->uniques)
unknown's avatar
unknown committed
8677 8678
    {
      /* Can't create a key; Make a unique constraint instead of a key */
8679 8680
      table->s->keys=    0;
      table->s->uniques= 1;
unknown's avatar
unknown committed
8681 8682 8683 8684 8685 8686 8687 8688 8689 8690 8691
      using_unique_constraint=1;
      bzero((char*) &uniquedef,sizeof(uniquedef));
      uniquedef.keysegs=keyinfo->key_parts;
      uniquedef.seg=seg;
      uniquedef.null_are_equal=1;

      /* Create extra column for hash value */
      bzero((byte*) param->recinfo,sizeof(*param->recinfo));
      param->recinfo->type= FIELD_CHECK;
      param->recinfo->length=MI_UNIQUE_HASH_LENGTH;
      param->recinfo++;
8692
      table->s->reclength+=MI_UNIQUE_HASH_LENGTH;
unknown's avatar
unknown committed
8693 8694 8695 8696 8697 8698 8699 8700 8701 8702 8703 8704
    }
    else
    {
      /* Create an unique key */
      bzero((char*) &keydef,sizeof(keydef));
      keydef.flag=HA_NOSAME | HA_BINARY_PACK_KEY | HA_PACK_KEY;
      keydef.keysegs=  keyinfo->key_parts;
      keydef.seg= seg;
    }
    for (uint i=0; i < keyinfo->key_parts ; i++,seg++)
    {
      Field *field=keyinfo->key_part[i].field;
8705
      seg->flag=     0;
unknown's avatar
unknown committed
8706
      seg->language= field->charset()->number;
8707 8708
      seg->length=   keyinfo->key_part[i].length;
      seg->start=    keyinfo->key_part[i].offset;
unknown's avatar
unknown committed
8709 8710 8711 8712
      if (field->flags & BLOB_FLAG)
      {
	seg->type=
	((keyinfo->key_part[i].key_type & FIELDFLAG_BINARY) ?
8713
	 HA_KEYTYPE_VARBINARY2 : HA_KEYTYPE_VARTEXT2);
8714
	seg->bit_start= (uint8)(field->pack_length() - table->s->blob_ptr_size);
unknown's avatar
unknown committed
8715 8716 8717 8718 8719
	seg->flag= HA_BLOB_PART;
	seg->length=0;			// Whole blob in unique constraint
      }
      else
      {
8720
	seg->type= keyinfo->key_part[i].type;
8721 8722
        /* Tell handler if it can do suffic space compression */
	if (field->real_type() == MYSQL_TYPE_STRING &&
unknown's avatar
unknown committed
8723
	    keyinfo->key_part[i].length > 4)
8724
	  seg->flag|= HA_SPACE_PACK;
unknown's avatar
unknown committed
8725
      }
8726
      if (!(field->flags & NOT_NULL_FLAG))
unknown's avatar
unknown committed
8727 8728 8729
      {
	seg->null_bit= field->null_bit;
	seg->null_pos= (uint) (field->null_ptr - (uchar*) table->record[0]);
8730 8731 8732
	/*
	  We are using a GROUP BY on something that contains NULL
	  In this case we have to tell MyISAM that two NULL should
8733
	  on INSERT be regarded at the same value
8734 8735 8736
	*/
	if (!using_unique_constraint)
	  keydef.flag|= HA_NULL_ARE_EQUAL;
unknown's avatar
unknown committed
8737 8738 8739 8740 8741
      }
    }
  }
  MI_CREATE_INFO create_info;
  bzero((char*) &create_info,sizeof(create_info));
unknown's avatar
unknown committed
8742

8743 8744
  if ((options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) ==
      OPTION_BIG_TABLES)
unknown's avatar
unknown committed
8745 8746
    create_info.data_file_length= ~(ulonglong) 0;

8747
  if ((error=mi_create(table->s->table_name,table->s->keys,&keydef,
unknown's avatar
unknown committed
8748 8749
		       (uint) (param->recinfo-param->start_recinfo),
		       param->start_recinfo,
8750
		       table->s->uniques, &uniquedef,
unknown's avatar
unknown committed
8751 8752 8753 8754 8755 8756 8757
		       &create_info,
		       HA_CREATE_TMP_TABLE)))
  {
    table->file->print_error(error,MYF(0));	/* purecov: inspected */
    table->db_stat=0;
    goto err;
  }
8758 8759
  statistic_increment(table->in_use->status_var.created_tmp_disk_tables,
		      &LOCK_status);
8760
  table->s->db_record_offset= 1;
unknown's avatar
unknown committed
8761 8762 8763 8764 8765 8766 8767 8768 8769 8770 8771
  DBUG_RETURN(0);
 err:
  DBUG_RETURN(1);
}


void
free_tmp_table(THD *thd, TABLE *entry)
{
  const char *save_proc_info;
  DBUG_ENTER("free_tmp_table");
8772
  DBUG_PRINT("enter",("table: %s",entry->alias));
unknown's avatar
unknown committed
8773 8774 8775

  save_proc_info=thd->proc_info;
  thd->proc_info="removing tmp table";
8776
  free_blobs(entry);
unknown's avatar
af  
unknown committed
8777
  if (entry->file)
unknown's avatar
unknown committed
8778
  {
unknown's avatar
af  
unknown committed
8779 8780 8781 8782 8783 8784 8785 8786 8787
    if (entry->db_stat)
    {
      (void) entry->file->close();
    }
    /*
      We can't call ha_delete_table here as the table may created in mixed case
      here and we have to ensure that delete_table gets the table name in
      the original case.
    */
8788 8789 8790
    if (!(test_flags & TEST_KEEP_TMP_TABLES) ||
        entry->s->db_type == DB_TYPE_HEAP)
      entry->file->delete_table(entry->s->table_name);
unknown's avatar
unknown committed
8791 8792
    delete entry->file;
  }
unknown's avatar
af  
unknown committed
8793

unknown's avatar
unknown committed
8794 8795
  /* free blobs */
  for (Field **ptr=entry->field ; *ptr ; ptr++)
8796
    (*ptr)->free();
unknown's avatar
unknown committed
8797 8798
  my_free((gptr) entry->record[0],MYF(0));
  free_io_cache(entry);
8799

unknown's avatar
unknown committed
8800
  bitmap_clear_bit(&temp_pool, entry->temp_pool_slot);
8801

unknown's avatar
unknown committed
8802 8803 8804 8805 8806 8807 8808 8809 8810 8811
  my_free((gptr) entry,MYF(0));
  thd->proc_info=save_proc_info;

  DBUG_VOID_RETURN;
}

/*
* If a HEAP table gets full, create a MyISAM table and copy all rows to this
*/

unknown's avatar
unknown committed
8812 8813
bool create_myisam_from_heap(THD *thd, TABLE *table, TMP_TABLE_PARAM *param,
			     int error, bool ignore_last_dupp_key_error)
unknown's avatar
unknown committed
8814 8815 8816 8817 8818 8819
{
  TABLE new_table;
  const char *save_proc_info;
  int write_err;
  DBUG_ENTER("create_myisam_from_heap");

8820
  if (table->s->db_type != DB_TYPE_HEAP || error != HA_ERR_RECORD_FILE_FULL)
unknown's avatar
unknown committed
8821 8822 8823 8824 8825
  {
    table->file->print_error(error,MYF(0));
    DBUG_RETURN(1);
  }
  new_table= *table;
8826 8827 8828
  new_table.s= &new_table.share_not_to_be_used;
  new_table.s->db_type= DB_TYPE_MYISAM;
  if (!(new_table.file= get_new_handler(&new_table,DB_TYPE_MYISAM)))
unknown's avatar
unknown committed
8829 8830 8831 8832 8833 8834
    DBUG_RETURN(1);				// End of memory

  save_proc_info=thd->proc_info;
  thd->proc_info="converting HEAP to MyISAM";

  if (create_myisam_tmp_table(&new_table,param,
unknown's avatar
unknown committed
8835
			      thd->lex->select_lex.options | thd->options))
unknown's avatar
unknown committed
8836 8837 8838
    goto err2;
  if (open_tmp_table(&new_table))
    goto err1;
unknown's avatar
af  
unknown committed
8839 8840
  if (table->file->indexes_are_disabled())
    new_table.file->disable_indexes(HA_KEY_SWITCH_ALL);
unknown's avatar
unknown committed
8841
  table->file->ha_index_or_rnd_end();
8842
  table->file->ha_rnd_init(1);
8843 8844
  if (table->no_rows)
  {
8845 8846
    new_table.file->extra(HA_EXTRA_NO_ROWS);
    new_table.no_rows=1;
8847 8848
  }

8849 8850 8851 8852 8853 8854 8855 8856 8857 8858 8859 8860
#ifdef TO_BE_DONE_LATER_IN_4_1
  /*
    To use start_bulk_insert() (which is new in 4.1) we need to find
    all places where a corresponding end_bulk_insert() should be put.
  */
  table->file->info(HA_STATUS_VARIABLE); /* update table->file->records */
  new_table.file->start_bulk_insert(table->file->records);
#else
  /* HA_EXTRA_WRITE_CACHE can stay until close, no need to disable it */
  new_table.file->extra(HA_EXTRA_WRITE_CACHE);
#endif

unknown's avatar
unknown committed
8861 8862 8863 8864 8865 8866 8867 8868 8869 8870 8871 8872 8873 8874 8875
  /* copy all old rows */
  while (!table->file->rnd_next(new_table.record[1]))
  {
    if ((write_err=new_table.file->write_row(new_table.record[1])))
      goto err;
  }
  /* copy row that filled HEAP table */
  if ((write_err=new_table.file->write_row(table->record[0])))
  {
    if (write_err != HA_ERR_FOUND_DUPP_KEY &&
	write_err != HA_ERR_FOUND_DUPP_UNIQUE || !ignore_last_dupp_key_error)
    goto err;
  }

  /* remove heap table and change to use myisam table */
unknown's avatar
unknown committed
8876
  (void) table->file->ha_rnd_end();
unknown's avatar
unknown committed
8877
  (void) table->file->close();
8878
  (void) table->file->delete_table(table->s->table_name);
unknown's avatar
unknown committed
8879 8880
  delete table->file;
  table->file=0;
8881 8882
  *table= new_table;
  table->s= &table->share_not_to_be_used;
unknown's avatar
unknown committed
8883
  table->file->change_table_ptr(table);
8884 8885 8886
  if (save_proc_info)
    thd->proc_info= (!strcmp(save_proc_info,"Copying to tmp table") ?
                     "Copying to tmp table on disk" : save_proc_info);
unknown's avatar
unknown committed
8887 8888 8889 8890 8891
  DBUG_RETURN(0);

 err:
  DBUG_PRINT("error",("Got error: %d",write_err));
  table->file->print_error(error,MYF(0));	// Give table is full error
unknown's avatar
unknown committed
8892
  (void) table->file->ha_rnd_end();
unknown's avatar
unknown committed
8893 8894
  (void) new_table.file->close();
 err1:
8895
  new_table.file->delete_table(new_table.s->table_name);
unknown's avatar
unknown committed
8896 8897 8898 8899 8900 8901 8902
  delete new_table.file;
 err2:
  thd->proc_info=save_proc_info;
  DBUG_RETURN(1);
}


8903 8904 8905 8906
/*
  SYNOPSIS
    setup_end_select_func()
    join   join to setup the function for.
unknown's avatar
unknown committed
8907

8908 8909 8910 8911
  DESCRIPTION
    Rows produced by a join sweep may end up in a temporary table or be sent
    to a client. Setup the function of the nested loop join algorithm which
    handles final fully constructed and matched records.
unknown's avatar
unknown committed
8912

8913 8914 8915
  RETURN
    end_select function to use. This function can't fail.
*/
unknown's avatar
unknown committed
8916

8917 8918 8919 8920
static Next_select_func setup_end_select_func(JOIN *join)
{
  TABLE *table= join->tmp_table;
  Next_select_func end_select;
unknown's avatar
unknown committed
8921 8922 8923 8924 8925
  /* Set up select_end */
  if (table)
  {
    if (table->group && join->tmp_table_param.sum_func_count)
    {
8926
      if (table->s->keys)
unknown's avatar
unknown committed
8927
      {
8928
	DBUG_PRINT("info",("Using end_update"));
unknown's avatar
unknown committed
8929 8930 8931
	end_select=end_update;
      }
      else
8932 8933
      {
	DBUG_PRINT("info",("Using end_unique_update"));
unknown's avatar
unknown committed
8934
	end_select=end_unique_update;
8935
      }
unknown's avatar
unknown committed
8936 8937 8938 8939 8940 8941 8942 8943 8944 8945 8946 8947 8948 8949
    }
    else if (join->sort_and_group)
    {
      DBUG_PRINT("info",("Using end_write_group"));
      end_select=end_write_group;
    }
    else
    {
      DBUG_PRINT("info",("Using end_write"));
      end_select=end_write;
    }
  }
  else
  {
8950 8951 8952 8953 8954 8955 8956 8957 8958 8959
    /* Test if data is accessed via QUICK_GROUP_MIN_MAX_SELECT. */
    bool is_using_quick_group_min_max_select=
      (join->join_tab->select && join->join_tab->select->quick &&
       (join->join_tab->select->quick->get_type() ==
        QUICK_SELECT_I::QS_TYPE_GROUP_MIN_MAX));

    if ((join->sort_and_group ||
         (join->procedure && join->procedure->flags & PROC_GROUP)) &&
        !is_using_quick_group_min_max_select)
      end_select= end_send_group;
unknown's avatar
unknown committed
8960
    else
8961
      end_select= end_send;
unknown's avatar
unknown committed
8962
  }
8963 8964 8965 8966 8967 8968 8969 8970 8971 8972 8973 8974 8975 8976
  return end_select;
}


/****************************************************************************
  Make a join of all tables and write it on socket or to table
  Return:  0 if ok
           1 if error is sent
          -1 if error should be sent
****************************************************************************/

static int
do_select(JOIN *join,List<Item> *fields,TABLE *table,Procedure *procedure)
{
8977 8978
  int rc= 0;
  enum_nested_loop_state error= NESTED_LOOP_OK;
8979 8980 8981 8982 8983 8984 8985 8986 8987 8988 8989 8990 8991 8992 8993 8994 8995
  JOIN_TAB *join_tab;
  DBUG_ENTER("do_select");

  join->procedure=procedure;
  join->tmp_table= table;			/* Save for easy recursion */
  join->fields= fields;

  if (table)
  {
    VOID(table->file->extra(HA_EXTRA_WRITE_CACHE));
    empty_record(table);
    if (table->group && join->tmp_table_param.sum_func_count &&
        table->s->keys && !table->file->inited)
      table->file->ha_index_init(0);
  }
  /* Set up select_end */
  join->join_tab[join->tables-1].next_select= setup_end_select_func(join);
unknown's avatar
unknown committed
8996 8997 8998 8999 9000

  join_tab=join->join_tab+join->const_tables;
  join->send_records=0;
  if (join->tables == join->const_tables)
  {
9001
    /*
9002
      HAVING will be checked after processing aggregate functions,
9003 9004
      But WHERE should checkd here (we alredy have read tables)
    */
unknown's avatar
unknown committed
9005
    if (!join->conds || join->conds->val_int())
unknown's avatar
unknown committed
9006
    {
9007
      Next_select_func end_select= join->join_tab[join->tables-1].next_select;
9008 9009 9010
      error= (*end_select)(join,join_tab,0);
      if (error == NESTED_LOOP_OK || error == NESTED_LOOP_QUERY_LIMIT)
	error= (*end_select)(join,join_tab,1);
unknown's avatar
unknown committed
9011
    }
unknown's avatar
af  
unknown committed
9012
    else if (join->send_row_on_empty_set())
9013
      rc= join->result->send_data(*join->fields);
unknown's avatar
unknown committed
9014 9015 9016
  }
  else
  {
unknown's avatar
unknown committed
9017
    error= sub_select(join,join_tab,0);
9018
    if (error == NESTED_LOOP_OK || error == NESTED_LOOP_NO_MORE_ROWS)
unknown's avatar
unknown committed
9019
      error= sub_select(join,join_tab,1);
9020 9021
    if (error == NESTED_LOOP_QUERY_LIMIT)
      error= NESTED_LOOP_OK;                    /* select_limit used */
unknown's avatar
unknown committed
9022
  }
9023 9024
  if (error == NESTED_LOOP_NO_MORE_ROWS)
    error= NESTED_LOOP_OK;
9025

9026
  if (error == NESTED_LOOP_OK)
unknown's avatar
unknown committed
9027
  {
9028 9029 9030 9031
    /*
      Sic: this branch works even if rc != 0, e.g. when
      send_data above returns an error.
    */
9032
    if (!table)					// If sending data to client
9033
    {
9034
      /*
9035 9036
	The following will unlock all cursors if the command wasn't an
	update command
9037
      */
9038
      join->join_free(0);				// Unlock all cursors
9039
      if (join->result->send_eof())
9040
	rc= 1;                                  // Don't send error
9041
    }
unknown's avatar
unknown committed
9042 9043
    DBUG_PRINT("info",("%ld records output",join->send_records));
  }
9044 9045
  else
    rc= -1;
unknown's avatar
unknown committed
9046 9047
  if (table)
  {
9048
    int tmp, new_errno= 0;
unknown's avatar
unknown committed
9049 9050
    if ((tmp=table->file->extra(HA_EXTRA_NO_CACHE)))
    {
9051
      DBUG_PRINT("error",("extra(HA_EXTRA_NO_CACHE) failed"));
9052
      new_errno= tmp;
unknown's avatar
unknown committed
9053
    }
unknown's avatar
unknown committed
9054
    if ((tmp=table->file->ha_index_or_rnd_end()))
unknown's avatar
unknown committed
9055
    {
unknown's avatar
unknown committed
9056
      DBUG_PRINT("error",("ha_index_or_rnd_end() failed"));
9057
      new_errno= tmp;
unknown's avatar
unknown committed
9058
    }
9059 9060
    if (new_errno)
      table->file->print_error(new_errno,MYF(0));
unknown's avatar
unknown committed
9061
  }
9062
#ifndef DBUG_OFF
9063
  if (rc)
9064 9065 9066 9067
  {
    DBUG_PRINT("error",("Error: do_select() failed"));
  }
#endif
9068
  DBUG_RETURN(join->thd->net.report_error ? -1 : rc);
unknown's avatar
unknown committed
9069 9070 9071
}


9072
static enum_nested_loop_state
unknown's avatar
unknown committed
9073 9074
sub_select_cache(JOIN *join,JOIN_TAB *join_tab,bool end_of_records)
{
9075
  enum_nested_loop_state rc;
unknown's avatar
unknown committed
9076 9077 9078

  if (end_of_records)
  {
9079 9080 9081 9082
    rc= flush_cached_records(join,join_tab,FALSE);
    if (rc == NESTED_LOOP_OK || rc == NESTED_LOOP_NO_MORE_ROWS)
      rc= sub_select(join,join_tab,end_of_records);
    return rc;
unknown's avatar
unknown committed
9083
  }
9084 9085
  if (join->thd->killed)		// If aborted by user
  {
unknown's avatar
SCRUM  
unknown committed
9086
    join->thd->send_kill_message();
9087
    return NESTED_LOOP_KILLED;                   /* purecov: inspected */
9088
  }
unknown's avatar
unknown committed
9089 9090 9091
  if (join_tab->use_quick != 2 || test_if_quick_select(join_tab) <= 0)
  {
    if (!store_record_in_cache(&join_tab->cache))
9092
      return NESTED_LOOP_OK;                     // There is more room in cache
unknown's avatar
unknown committed
9093 9094
    return flush_cached_records(join,join_tab,FALSE);
  }
9095 9096 9097 9098
  rc= flush_cached_records(join, join_tab, TRUE);
  if (rc == NESTED_LOOP_OK || rc == NESTED_LOOP_NO_MORE_ROWS)
    rc= sub_select(join, join_tab, end_of_records);
  return rc;
unknown's avatar
unknown committed
9099 9100
}

9101 9102 9103 9104 9105 9106 9107 9108 9109 9110 9111 9112 9113 9114 9115 9116 9117 9118 9119 9120 9121 9122 9123 9124 9125 9126 9127 9128 9129 9130 9131 9132 9133 9134 9135 9136 9137 9138 9139 9140 9141 9142 9143 9144 9145 9146 9147 9148 9149 9150 9151 9152 9153 9154 9155 9156 9157 9158 9159 9160 9161 9162 9163 9164 9165 9166 9167 9168 9169 9170 9171 9172 9173 9174 9175 9176 9177 9178 9179 9180 9181 9182 9183 9184 9185 9186 9187 9188 9189 9190 9191 9192 9193 9194 9195 9196 9197 9198 9199 9200 9201 9202 9203 9204
/*
  Retrieve records ends with a given beginning from the result of a join  

  SYNPOSIS
    sub_select()
    join      pointer to the structure providing all context info for the query
    join_tab  the first next table of the execution plan to be retrieved
    end_records  true when we need to perform final steps of retrival   

  DESCRIPTION
    For a given partial join record consisting of records from the tables 
    preceding the table join_tab in the execution plan, the function
    retrieves all matching full records from the result set and
    send them to the result set stream. 

  NOTES
    The function effectively implements the  final (n-k) nested loops
    of nested loops join algorithm, where k is the ordinal number of
    the join_tab table and n is the total number of tables in the join query.
    It performs nested loops joins with all conjunctive predicates from
    the where condition pushed as low to the tables as possible.
    E.g. for the query
      SELECT * FROM t1,t2,t3 
        WHERE t1.a=t2.a AND t2.b=t3.b AND t1.a BETWEEN 5 AND 9
    the predicate (t1.a BETWEEN 5 AND 9) will be pushed to table t1,
    given the selected plan prescribes to nest retrievals of the
    joined tables in the following order: t1,t2,t3.
    A pushed down predicate are attached to the table which it pushed to,
    at the field select_cond.
    When executing a nested loop of level k the function runs through
    the rows of 'join_tab' and for each row checks the pushed condition
    attached to the table.
    If it is false the function moves to the next row of the
    table. If the condition is true the function recursively executes (n-k-1)
    remaining embedded nested loops.
    The situation becomes more complicated if outer joins are involved in
    the execution plan. In this case the pushed down predicates can be
    checked only at certain conditions.
    Suppose for the query
      SELECT * FROM t1 LEFT JOIN (t2,t3) ON t3.a=t1.a 
        WHERE t1>2 AND (t2.b>5 OR t2.b IS NULL)
    the optimizer has chosen a plan with the table order t1,t2,t3.  
    The predicate P1=t1>2 will be pushed down to the table t1, while the
    predicate P2=(t2.b>5 OR t2.b IS NULL) will be attached to the table
    t2. But the second predicate can not be unconditionally tested right
    after a row from t2 has been read. This can be done only after the
    first row with t3.a=t1.a has been encountered.
    Thus, the second predicate P2 is supplied with a guarded value that are
    stored in the field 'found' of the first inner table for the outer join
    (table t2). When the first row with t3.a=t1.a for the  current row 
    of table t1  appears, the value becomes true. For now on the predicate
    is evaluated immediately after the row of table t2 has been read.
    When the first row with t3.a=t1.a has been encountered all
    conditions attached to the inner tables t2,t3 must be evaluated.
    Only when all of them are true the row is sent to the output stream.
    If not, the function returns to the lowest nest level that has a false
    attached condition.
    The predicates from on expressions are also pushed down. If in the 
    the above example the on expression were (t3.a=t1.a AND t2.a=t1.a),
    then t1.a=t2.a would be pushed down to table t2, and without any
    guard.
    If after the run through all rows of table t2, the first inner table
    for the outer join operation, it turns out that no matches are
    found for the current row of t1, then current row from table t1
    is complemented by nulls  for t2 and t3. Then the pushed down predicates
    are checked for the composed row almost in the same way as it had
    been done for the first row with a match. The only difference is
    the predicates  from on expressions are not checked. 

  IMPLEMENTATION
    The function forms output rows for a current partial join of k
    tables tables recursively.
    For each partial join record ending with a certain row from
    join_tab it calls sub_select that builds all possible matching
    tails from the result set.
    To be able  check predicates conditionally items of the class
    Item_func_trig_cond  are employed.
    An object of  this class is constructed from an item of class COND
    and a pointer to a guarding boolean variable.
    When the value of the guard variable is true the value of the object
    is the same as the value of the predicate, otherwise it's just returns
    true. 
    To carry out a return to a nested loop level of join table t the pointer 
    to t is remembered in the field 'return_tab' of the join structure.
    Consider the following query:
      SELECT * FROM t1,
                    LEFT JOIN
                    (t2, t3 LEFT JOIN (t4,t5) ON t5.a=t3.a)
                    ON t4.a=t2.a
         WHERE (t2.b=5 OR t2.b IS NULL) AND (t4.b=2 OR t4.b IS NULL)
    Suppose the chosen execution plan dictates the order t1,t2,t3,t4,t5
    and suppose for a given joined rows from tables t1,t2,t3 there are
    no rows in the result set yet.
    When first row from t5 that satisfies the on condition
    t5.a=t3.a is found, the pushed down predicate t4.b=2 OR t4.b IS NULL
    becomes 'activated', as well the predicate t4.a=t2.a. But
    the predicate (t2.b=5 OR t2.b IS NULL) can not be checked until
    t4.a=t2.a becomes true. 
    In order not to re-evaluate the predicates that were already evaluated
    as attached pushed down predicates, a pointer to the the first
    most inner unmatched table is maintained in join_tab->first_unmatched.
    Thus, when the first row from t5 with t5.a=t3.a is found
    this pointer for t5 is changed from t4 to t2.             

unknown's avatar
unknown committed
9205 9206 9207 9208
  STRUCTURE NOTES
    join_tab->first_unmatched points always backwards to the first inner
    table of the embedding nested join, if any.

9209
  RETURN
9210
    return one of enum_nested_loop_state, except NESTED_LOOP_NO_MORE_ROWS.
9211
*/
unknown's avatar
unknown committed
9212

9213
static enum_nested_loop_state
unknown's avatar
unknown committed
9214 9215 9216 9217 9218 9219 9220
sub_select(JOIN *join,JOIN_TAB *join_tab,bool end_of_records)
{
  join_tab->table->null_row=0;
  if (end_of_records)
    return (*join_tab->next_select)(join,join_tab+1,end_of_records);

  int error;
9221
  enum_nested_loop_state rc;
9222
  my_bool *report_error= &(join->thd->net.report_error);
9223
  READ_RECORD *info= &join_tab->read_record;
9224

9225 9226 9227 9228 9229 9230 9231 9232 9233 9234 9235 9236
  if (join->resume_nested_loop)
  {
    /* If not the last table, plunge down the nested loop */
    if (join_tab < join->join_tab + join->tables - 1)
      rc= (*join_tab->next_select)(join, join_tab + 1, 0);
    else
    {
      join->resume_nested_loop= FALSE;
      rc= NESTED_LOOP_OK;
    }
  }
  else
unknown's avatar
unknown committed
9237
  {
9238
    join->return_tab= join_tab;
9239

9240 9241 9242
    if (join_tab->last_inner)
    {
      /* join_tab is the first inner table for an outer join operation. */
9243

9244 9245 9246 9247 9248 9249 9250 9251 9252 9253 9254
      /* Set initial state of guard variables for this table.*/
      join_tab->found=0;
      join_tab->not_null_compl= 1;

      /* Set first_unmatched for the last inner table of this group */
      join_tab->last_inner->first_unmatched= join_tab;
    }
    join->thd->row_count= 0;

    error= (*join_tab->read_first_record)(join_tab);
    rc= evaluate_join_record(join, join_tab, error, report_error);
9255 9256
  }

9257
  while (rc == NESTED_LOOP_OK)
unknown's avatar
unknown committed
9258
  {
9259 9260 9261
    error= info->read_record(info);
    rc= evaluate_join_record(join, join_tab, error, report_error);
  }
unknown's avatar
unknown committed
9262

9263 9264 9265 9266 9267 9268 9269 9270 9271 9272 9273 9274 9275 9276 9277 9278 9279 9280 9281 9282 9283 9284 9285 9286 9287 9288 9289 9290 9291 9292 9293 9294 9295 9296 9297 9298 9299 9300 9301 9302 9303 9304 9305 9306 9307 9308
  if (rc == NESTED_LOOP_NO_MORE_ROWS &&
      join_tab->last_inner && !join_tab->found)
    rc= evaluate_null_complemented_join_record(join, join_tab);

  if (rc == NESTED_LOOP_NO_MORE_ROWS)
    rc= NESTED_LOOP_OK;
  return rc;
}


/*
  Process one record of the nested loop join.

  DESCRIPTION
    This function will evaluate parts of WHERE/ON clauses that are
    applicable to the partial record on hand and in case of success
    submit this record to the next level of the nested loop.
*/

static enum_nested_loop_state
evaluate_join_record(JOIN *join, JOIN_TAB *join_tab,
                     int error, my_bool *report_error)
{
  bool not_exists_optimize= join_tab->table->reginfo.not_exists_optimize;
  bool not_used_in_distinct=join_tab->not_used_in_distinct;
  ha_rows found_records=join->found_records;
  COND *select_cond= join_tab->select_cond;

  if (error > 0 || (*report_error))				// Fatal error
    return NESTED_LOOP_ERROR;
  if (error < 0)
    return NESTED_LOOP_NO_MORE_ROWS;
  if (join->thd->killed)			// Aborted by user
  {
    join->thd->send_kill_message();
    return NESTED_LOOP_KILLED;               /* purecov: inspected */
  }
  DBUG_PRINT("info", ("select cond 0x%lx", (ulong)select_cond));
  if (!select_cond || select_cond->val_int())
  {
    /*
      There is no select condition or the attached pushed down
      condition is true => a match is found.
    */
    bool found= 1;
    while (join_tab->first_unmatched && found)
unknown's avatar
unknown committed
9309
    {
9310 9311 9312 9313 9314 9315 9316 9317 9318 9319 9320 9321
      /*
        The while condition is always false if join_tab is not
        the last inner join table of an outer join operation.
      */
      JOIN_TAB *first_unmatched= join_tab->first_unmatched;
      /*
        Mark that a match for current outer table is found.
        This activates push down conditional predicates attached
        to the all inner tables of the outer join.
      */
      first_unmatched->found= 1;
      for (JOIN_TAB *tab= first_unmatched; tab <= join_tab; tab++)
unknown's avatar
unknown committed
9322
      {
9323 9324 9325 9326 9327 9328 9329
        /* Check all predicates that has just been activated. */
        /*
          Actually all predicates non-guarded by first_unmatched->found
          will be re-evaluated again. It could be fixed, but, probably,
          it's not worth doing now.
        */
        if (tab->select_cond && !tab->select_cond->val_int())
9330
        {
9331 9332 9333 9334 9335
          /* The condition attached to table tab is false */
          if (tab == join_tab)
            found= 0;
          else
          {
9336
            /*
9337 9338 9339 9340 9341
              Set a return point if rejected predicate is attached
              not to the last table of the current nest level.
            */
            join->return_tab= tab;
            return NESTED_LOOP_OK;
9342 9343 9344
          }
        }
      }
9345 9346 9347 9348
      /*
        Check whether join_tab is not the last inner table
        for another embedding outer join.
      */
9349 9350 9351 9352
      if ((first_unmatched= first_unmatched->first_upper) &&
          first_unmatched->last_inner != join_tab)
        first_unmatched= 0;
      join_tab->first_unmatched= first_unmatched;
unknown's avatar
unknown committed
9353
    }
9354 9355 9356 9357 9358 9359 9360 9361 9362 9363 9364 9365 9366 9367 9368 9369 9370 9371 9372 9373 9374 9375 9376 9377 9378 9379 9380 9381 9382 9383 9384 9385 9386

    /*
      It was not just a return to lower loop level when one
      of the newly activated predicates is evaluated as false
      (See above join->return_tab= tab).
    */
    join->examined_rows++;
    join->thd->row_count++;

    if (found)
    {
      enum enum_nested_loop_state rc;
      if (not_exists_optimize)
        return NESTED_LOOP_NO_MORE_ROWS;
      /* A match from join_tab is found for the current partial join. */
      rc= (*join_tab->next_select)(join, join_tab+1, 0);
      if (rc != NESTED_LOOP_OK && rc != NESTED_LOOP_NO_MORE_ROWS)
        return rc;
      if (join->return_tab < join_tab)
        return NESTED_LOOP_OK;
      /*
        Test if this was a SELECT DISTINCT query on a table that
        was not in the field list;  In this case we can abort if
        we found a row, as no new rows can be added to the result.
      */
      if (not_used_in_distinct && found_records != join->found_records)
        return NESTED_LOOP_OK;
    }
    else
      join_tab->read_record.file->unlock_row();
  }
  else
  {
9387
    /*
9388 9389 9390 9391 9392
      The condition pushed down to the table join_tab rejects all rows
      with the beginning coinciding with the current partial join.
    */
    join->examined_rows++;
    join->thd->row_count++;
unknown's avatar
unknown committed
9393
  }
9394
  return NESTED_LOOP_OK;
unknown's avatar
unknown committed
9395 9396 9397
}


9398 9399 9400 9401 9402 9403 9404 9405 9406 9407 9408 9409 9410 9411 9412 9413 9414 9415 9416 9417 9418 9419 9420 9421 9422 9423 9424 9425 9426 9427 9428 9429 9430 9431 9432 9433 9434 9435 9436 9437 9438 9439 9440 9441 9442 9443 9444 9445 9446 9447 9448 9449 9450 9451 9452 9453 9454 9455 9456 9457 9458 9459 9460 9461 9462 9463 9464
/*
  DESCRIPTION
    Construct a NULL complimented partial join record and feed it to the next
    level of the nested loop. This function is used in case we have
    an OUTER join and no matching record was found.
*/

static enum_nested_loop_state
evaluate_null_complemented_join_record(JOIN *join, JOIN_TAB *join_tab)
{
  /*
    The table join_tab is the first inner table of a outer join operation
    and no matches has been found for the current outer row.
  */
  JOIN_TAB *last_inner_tab= join_tab->last_inner;
  /* Cache variables for faster loop */
  COND *select_cond;
  for ( ; join_tab <= last_inner_tab ; join_tab++)
  {
    /* Change the the values of guard predicate variables. */
    join_tab->found= 1;
    join_tab->not_null_compl= 0;
    /* The outer row is complemented by nulls for each inner tables */
    restore_record(join_tab->table,s->default_values);  // Make empty record
    mark_as_null_row(join_tab->table);       // For group by without error
    select_cond= join_tab->select_cond;
    /* Check all attached conditions for inner table rows. */
    if (select_cond && !select_cond->val_int())
      return NESTED_LOOP_OK;
  }
  join_tab--;
  /*
    The row complemented by nulls might be the first row
    of embedding outer joins.
    If so, perform the same actions as in the code
    for the first regular outer join row above.
  */
  for ( ; ; )
  {
    JOIN_TAB *first_unmatched= join_tab->first_unmatched;
    if ((first_unmatched= first_unmatched->first_upper) &&
        first_unmatched->last_inner != join_tab)
      first_unmatched= 0;
    join_tab->first_unmatched= first_unmatched;
    if (!first_unmatched)
      break;
    first_unmatched->found= 1;
    for (JOIN_TAB *tab= first_unmatched; tab <= join_tab; tab++)
    {
      if (tab->select_cond && !tab->select_cond->val_int())
      {
        join->return_tab= tab;
        return NESTED_LOOP_OK;
      }
    }
  }
  /*
    The row complemented by nulls satisfies all conditions
    attached to inner tables.
    Send the row complemented by nulls to be joined with the
    remaining tables.
  */
  return (*join_tab->next_select)(join, join_tab+1, 0);
}


static enum_nested_loop_state
unknown's avatar
af  
unknown committed
9465
flush_cached_records(JOIN *join,JOIN_TAB *join_tab,bool skip_last)
unknown's avatar
unknown committed
9466
{
9467
  enum_nested_loop_state rc= NESTED_LOOP_OK;
unknown's avatar
unknown committed
9468 9469 9470 9471
  int error;
  READ_RECORD *info;

  if (!join_tab->cache.records)
9472
    return NESTED_LOOP_OK;                      /* Nothing to do */
unknown's avatar
af  
unknown committed
9473
  if (skip_last)
unknown's avatar
unknown committed
9474 9475 9476 9477 9478 9479 9480 9481 9482 9483 9484 9485
    (void) store_record_in_cache(&join_tab->cache); // Must save this for later
  if (join_tab->use_quick == 2)
  {
    if (join_tab->select->quick)
    {					/* Used quick select last. reset it */
      delete join_tab->select->quick;
      join_tab->select->quick=0;
    }
  }
 /* read through all records */
  if ((error=join_init_read_record(join_tab)))
  {
9486
    reset_cache_write(&join_tab->cache);
9487
    return error < 0 ? NESTED_LOOP_NO_MORE_ROWS: NESTED_LOOP_ERROR;
unknown's avatar
unknown committed
9488 9489 9490 9491 9492 9493 9494 9495 9496 9497 9498 9499 9500
  }

  for (JOIN_TAB *tmp=join->join_tab; tmp != join_tab ; tmp++)
  {
    tmp->status=tmp->table->status;
    tmp->table->status=0;
  }

  info= &join_tab->read_record;
  do
  {
    if (join->thd->killed)
    {
unknown's avatar
SCRUM  
unknown committed
9501
      join->thd->send_kill_message();
9502
      return NESTED_LOOP_KILLED; // Aborted by user /* purecov: inspected */
unknown's avatar
unknown committed
9503 9504
    }
    SQL_SELECT *select=join_tab->select;
9505 9506
    if (rc == NESTED_LOOP_OK &&
        (!join_tab->cache.select || !join_tab->cache.select->skip_record()))
unknown's avatar
unknown committed
9507 9508
    {
      uint i;
9509
      reset_cache_read(&join_tab->cache);
unknown's avatar
af  
unknown committed
9510
      for (i=(join_tab->cache.records- (skip_last ? 1 : 0)) ; i-- > 0 ;)
unknown's avatar
unknown committed
9511 9512
      {
	read_cached_record(join_tab);
unknown's avatar
af  
unknown committed
9513
	if (!select || !select->skip_record())
9514 9515 9516
        {
          rc= (join_tab->next_select)(join,join_tab+1,0);
	  if (rc != NESTED_LOOP_OK && rc != NESTED_LOOP_NO_MORE_ROWS)
9517 9518
          {
            reset_cache_write(&join_tab->cache);
9519
            return rc;
9520
          }
9521
        }
unknown's avatar
unknown committed
9522 9523 9524 9525
      }
    }
  } while (!(error=info->read_record(info)));

unknown's avatar
af  
unknown committed
9526
  if (skip_last)
unknown's avatar
unknown committed
9527
    read_cached_record(join_tab);		// Restore current record
9528
  reset_cache_write(&join_tab->cache);
unknown's avatar
unknown committed
9529
  if (error > 0)				// Fatal error
9530
    return NESTED_LOOP_ERROR;                   /* purecov: inspected */
unknown's avatar
unknown committed
9531 9532
  for (JOIN_TAB *tmp2=join->join_tab; tmp2 != join_tab ; tmp2++)
    tmp2->table->status=tmp2->status;
9533
  return NESTED_LOOP_OK;
unknown's avatar
unknown committed
9534 9535 9536 9537
}


/*****************************************************************************
9538 9539
  The different ways to read a record
  Returns -1 if row was not found, 0 if row was found and 1 on errors
unknown's avatar
unknown committed
9540
*****************************************************************************/
9541 9542 9543

/* Help function when we get some an error from the table handler */

9544
int report_error(TABLE *table, int error)
9545 9546 9547 9548 9549 9550 9551 9552 9553 9554 9555 9556
{
  if (error == HA_ERR_END_OF_FILE || error == HA_ERR_KEY_NOT_FOUND)
  {
    table->status= STATUS_GARBAGE;
    return -1;					// key not found; ok
  }
  /*
    Locking reads can legally return also these errors, do not
    print them to the .err log
  */
  if (error != HA_ERR_LOCK_DEADLOCK && error != HA_ERR_LOCK_WAIT_TIMEOUT)
    sql_print_error("Got error %d when reading table '%s'",
9557
		    error, table->s->path);
9558 9559 9560 9561 9562
  table->file->print_error(error,MYF(0));
  return 1;
}


9563
int safe_index_read(JOIN_TAB *tab)
9564 9565 9566 9567 9568 9569 9570 9571 9572 9573 9574
{
  int error;
  TABLE *table= tab->table;
  if ((error=table->file->index_read(table->record[0],
				     tab->ref.key_buff,
				     tab->ref.key_length, HA_READ_KEY_EXACT)))
    return report_error(table, error);
  return 0;
}


unknown's avatar
unknown committed
9575
static int
9576
join_read_const_table(JOIN_TAB *tab, POSITION *pos)
unknown's avatar
unknown committed
9577 9578
{
  int error;
9579 9580 9581 9582 9583 9584 9585
  DBUG_ENTER("join_read_const_table");
  TABLE *table=tab->table;
  table->const_table=1;
  table->null_row=0;
  table->status=STATUS_NO_RECORD;
  
  if (tab->type == JT_SYSTEM)
unknown's avatar
unknown committed
9586
  {
9587 9588 9589 9590 9591
    if ((error=join_read_system(tab)))
    {						// Info for DESCRIBE
      tab->info="const row not found";
      /* Mark for EXPLAIN that the row was not found */
      pos->records_read=0.0;
9592
      if (!table->maybe_null || error > 0)
9593
	DBUG_RETURN(error);
unknown's avatar
unknown committed
9594
    }
9595 9596 9597
  }
  else
  {
unknown's avatar
af  
unknown committed
9598
    if (!table->key_read && table->used_keys.is_set(tab->ref.key) &&
9599 9600
	!table->no_keyread &&
        (int) table->reginfo.lock_type <= (int) TL_READ_HIGH_PRIORITY)
unknown's avatar
af  
unknown committed
9601 9602 9603
    {
      table->key_read=1;
      table->file->extra(HA_EXTRA_KEYREAD);
unknown's avatar
unknown committed
9604
      tab->index= tab->ref.key;
unknown's avatar
af  
unknown committed
9605
    }
9606
    if ((error=join_read_const(tab)))
unknown's avatar
unknown committed
9607
    {
9608 9609 9610
      tab->info="unique row not found";
      /* Mark for EXPLAIN that the row was not found */
      pos->records_read=0.0;
9611
      if (!table->maybe_null || error > 0)
9612
	DBUG_RETURN(error);
unknown's avatar
unknown committed
9613
    }
unknown's avatar
unknown committed
9614 9615 9616 9617 9618
    if (table->key_read)
    {
      table->key_read=0;
      table->file->extra(HA_EXTRA_NO_KEYREAD);
    }
unknown's avatar
unknown committed
9619
  }
unknown's avatar
unknown committed
9620
  if (*tab->on_expr_ref && !table->null_row)
9621
  {
unknown's avatar
unknown committed
9622
    if ((table->null_row= test((*tab->on_expr_ref)->val_int() == 0)))
unknown's avatar
af  
unknown committed
9623 9624
      mark_as_null_row(table);  
  }
9625 9626
  if (!table->null_row)
    table->maybe_null=0;
unknown's avatar
unknown committed
9627 9628 9629 9630 9631 9632 9633 9634 9635 9636 9637
  DBUG_RETURN(0);
}


static int
join_read_system(JOIN_TAB *tab)
{
  TABLE *table= tab->table;
  int error;
  if (table->status & STATUS_GARBAGE)		// If first read
  {
9638
    if ((error=table->file->read_first_row(table->record[0],
9639
					   table->s->primary_key)))
unknown's avatar
unknown committed
9640 9641
    {
      if (error != HA_ERR_END_OF_FILE)
9642
	return report_error(table, error);
unknown's avatar
unknown committed
9643
      mark_as_null_row(tab->table);
unknown's avatar
unknown committed
9644 9645 9646
      empty_record(table);			// Make empty record
      return -1;
    }
unknown's avatar
unknown committed
9647
    store_record(table,record[1]);
unknown's avatar
unknown committed
9648 9649
  }
  else if (!table->status)			// Only happens with left join
unknown's avatar
unknown committed
9650
    restore_record(table,record[1]);			// restore old record
unknown's avatar
unknown committed
9651 9652 9653 9654 9655
  table->null_row=0;
  return table->status ? -1 : 0;
}


9656 9657 9658 9659 9660 9661 9662 9663 9664 9665 9666 9667 9668
/*
  Read a table when there is at most one matching row

  SYNOPSIS
    join_read_const()
    tab			Table to read

  RETURN
    0	Row was found
    -1  Row was not found
   1    Got an error (other than row not found) during read
*/

unknown's avatar
unknown committed
9669 9670 9671 9672 9673 9674 9675
static int
join_read_const(JOIN_TAB *tab)
{
  int error;
  TABLE *table= tab->table;
  if (table->status & STATUS_GARBAGE)		// If first read
  {
9676
    table->status= 0;
unknown's avatar
unknown committed
9677
    if (cp_buffer_from_ref(tab->join->thd, &tab->ref))
unknown's avatar
unknown committed
9678 9679 9680 9681 9682 9683 9684 9685 9686
      error=HA_ERR_KEY_NOT_FOUND;
    else
    {
      error=table->file->index_read_idx(table->record[0],tab->ref.key,
					(byte*) tab->ref.key_buff,
					tab->ref.key_length,HA_READ_KEY_EXACT);
    }
    if (error)
    {
9687
      table->status= STATUS_NOT_FOUND;
unknown's avatar
unknown committed
9688
      mark_as_null_row(tab->table);
unknown's avatar
unknown committed
9689 9690
      empty_record(table);
      if (error != HA_ERR_KEY_NOT_FOUND)
9691
	return report_error(table, error);
unknown's avatar
unknown committed
9692 9693
      return -1;
    }
unknown's avatar
unknown committed
9694
    store_record(table,record[1]);
unknown's avatar
unknown committed
9695
  }
unknown's avatar
unknown committed
9696 9697 9698
  else if (!(table->status & ~STATUS_NULL_ROW))	// Only happens with left join
  {
    table->status=0;
unknown's avatar
unknown committed
9699
    restore_record(table,record[1]);			// restore old record
unknown's avatar
unknown committed
9700
  }
unknown's avatar
unknown committed
9701 9702 9703 9704 9705 9706 9707 9708 9709 9710 9711
  table->null_row=0;
  return table->status ? -1 : 0;
}


static int
join_read_key(JOIN_TAB *tab)
{
  int error;
  TABLE *table= tab->table;

unknown's avatar
unknown committed
9712 9713
  if (!table->file->inited)
    table->file->ha_index_init(tab->ref.key);
unknown's avatar
unknown committed
9714
  if (cmp_buffer_with_ref(tab) ||
9715
      (table->status & (STATUS_GARBAGE | STATUS_NO_PARENT | STATUS_NULL_ROW)))
unknown's avatar
unknown committed
9716 9717 9718 9719 9720 9721 9722 9723 9724 9725
  {
    if (tab->ref.key_err)
    {
      table->status=STATUS_NOT_FOUND;
      return -1;
    }
    error=table->file->index_read(table->record[0],
				  tab->ref.key_buff,
				  tab->ref.key_length,HA_READ_KEY_EXACT);
    if (error && error != HA_ERR_KEY_NOT_FOUND)
9726
      return report_error(table, error);
unknown's avatar
unknown committed
9727
  }
9728
  table->null_row=0;
unknown's avatar
unknown committed
9729 9730 9731 9732 9733 9734 9735 9736 9737 9738
  return table->status ? -1 : 0;
}


static int
join_read_always_key(JOIN_TAB *tab)
{
  int error;
  TABLE *table= tab->table;

unknown's avatar
unknown committed
9739 9740
  if (!table->file->inited)
    table->file->ha_index_init(tab->ref.key);
unknown's avatar
unknown committed
9741
  if (cp_buffer_from_ref(tab->join->thd, &tab->ref))
unknown's avatar
unknown committed
9742 9743 9744 9745 9746 9747
    return -1;
  if ((error=table->file->index_read(table->record[0],
				     tab->ref.key_buff,
				     tab->ref.key_length,HA_READ_KEY_EXACT)))
  {
    if (error != HA_ERR_KEY_NOT_FOUND)
9748
      return report_error(table, error);
unknown's avatar
unknown committed
9749 9750 9751 9752 9753
    return -1; /* purecov: inspected */
  }
  return 0;
}

9754

9755 9756 9757 9758 9759 9760 9761 9762 9763 9764 9765
/*
  This function is used when optimizing away ORDER BY in 
  SELECT * FROM t1 WHERE a=1 ORDER BY a DESC,b DESC
*/
  
static int
join_read_last_key(JOIN_TAB *tab)
{
  int error;
  TABLE *table= tab->table;

unknown's avatar
unknown committed
9766 9767
  if (!table->file->inited)
    table->file->ha_index_init(tab->ref.key);
unknown's avatar
unknown committed
9768
  if (cp_buffer_from_ref(tab->join->thd, &tab->ref))
9769 9770 9771 9772 9773 9774
    return -1;
  if ((error=table->file->index_read_last(table->record[0],
					  tab->ref.key_buff,
					  tab->ref.key_length)))
  {
    if (error != HA_ERR_KEY_NOT_FOUND)
9775
      return report_error(table, error);
9776 9777 9778 9779 9780
    return -1; /* purecov: inspected */
  }
  return 0;
}

unknown's avatar
unknown committed
9781 9782 9783 9784 9785 9786 9787 9788 9789 9790

	/* ARGSUSED */
static int
join_no_more_records(READ_RECORD *info __attribute__((unused)))
{
  return -1;
}


static int
9791
join_read_next_same(READ_RECORD *info)
unknown's avatar
unknown committed
9792 9793 9794 9795 9796 9797 9798 9799 9800 9801
{
  int error;
  TABLE *table= info->table;
  JOIN_TAB *tab=table->reginfo.join_tab;

  if ((error=table->file->index_next_same(table->record[0],
					  tab->ref.key_buff,
					  tab->ref.key_length)))
  {
    if (error != HA_ERR_END_OF_FILE)
9802
      return report_error(table, error);
unknown's avatar
unknown committed
9803 9804 9805 9806 9807 9808
    table->status= STATUS_GARBAGE;
    return -1;
  }
  return 0;
}

9809

9810 9811 9812 9813 9814 9815 9816 9817
static int
join_read_prev_same(READ_RECORD *info)
{
  int error;
  TABLE *table= info->table;
  JOIN_TAB *tab=table->reginfo.join_tab;

  if ((error=table->file->index_prev(table->record[0])))
9818
    return report_error(table, error);
unknown's avatar
af  
unknown committed
9819 9820
  if (key_cmp_if_same(table, tab->ref.key_buff, tab->ref.key,
                      tab->ref.key_length))
9821 9822
  {
    table->status=STATUS_NOT_FOUND;
9823
    error= -1;
9824 9825 9826 9827
  }
  return error;
}

unknown's avatar
unknown committed
9828 9829 9830 9831 9832 9833 9834 9835 9836 9837 9838 9839 9840 9841 9842

static int
join_init_quick_read_record(JOIN_TAB *tab)
{
  if (test_if_quick_select(tab) == -1)
    return -1;					/* No possible records */
  return join_init_read_record(tab);
}


static int
test_if_quick_select(JOIN_TAB *tab)
{
  delete tab->select->quick;
  tab->select->quick=0;
9843
  return tab->select->test_quick_select(tab->join->thd, tab->keys,
9844
					(table_map) 0, HA_POS_ERROR, 0);
unknown's avatar
unknown committed
9845 9846 9847 9848 9849 9850
}


static int
join_init_read_record(JOIN_TAB *tab)
{
9851 9852
  if (tab->select && tab->select->quick && tab->select->quick->reset())
    return 1;
9853 9854
  init_read_record(&tab->read_record, tab->join->thd, tab->table,
		   tab->select,1,1);
unknown's avatar
unknown committed
9855 9856 9857
  return (*tab->read_record.read_record)(&tab->read_record);
}

9858

unknown's avatar
unknown committed
9859
static int
9860
join_read_first(JOIN_TAB *tab)
unknown's avatar
unknown committed
9861 9862 9863
{
  int error;
  TABLE *table=tab->table;
9864
  if (!table->key_read && table->used_keys.is_set(tab->index) &&
unknown's avatar
unknown committed
9865
      !table->no_keyread)
unknown's avatar
unknown committed
9866 9867 9868 9869 9870
  {
    table->key_read=1;
    table->file->extra(HA_EXTRA_KEYREAD);
  }
  tab->table->status=0;
9871
  tab->read_record.read_record=join_read_next;
unknown's avatar
unknown committed
9872 9873 9874 9875
  tab->read_record.table=table;
  tab->read_record.file=table->file;
  tab->read_record.index=tab->index;
  tab->read_record.record=table->record[0];
unknown's avatar
unknown committed
9876 9877
  if (!table->file->inited)
    table->file->ha_index_init(tab->index);
9878
  if ((error=tab->table->file->index_first(tab->table->record[0])))
unknown's avatar
unknown committed
9879 9880
  {
    if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
9881
      report_error(table, error);
unknown's avatar
unknown committed
9882 9883 9884 9885 9886
    return -1;
  }
  return 0;
}

9887

unknown's avatar
unknown committed
9888
static int
9889
join_read_next(READ_RECORD *info)
unknown's avatar
unknown committed
9890
{
9891 9892 9893
  int error;
  if ((error=info->file->index_next(info->record)))
    return report_error(info->table, error);
unknown's avatar
unknown committed
9894 9895 9896
  return 0;
}

9897

unknown's avatar
unknown committed
9898
static int
9899
join_read_last(JOIN_TAB *tab)
unknown's avatar
unknown committed
9900 9901 9902
{
  TABLE *table=tab->table;
  int error;
9903
  if (!table->key_read && table->used_keys.is_set(tab->index) &&
9904
      !table->no_keyread)
unknown's avatar
unknown committed
9905 9906 9907 9908 9909
  {
    table->key_read=1;
    table->file->extra(HA_EXTRA_KEYREAD);
  }
  tab->table->status=0;
9910
  tab->read_record.read_record=join_read_prev;
unknown's avatar
unknown committed
9911 9912 9913 9914
  tab->read_record.table=table;
  tab->read_record.file=table->file;
  tab->read_record.index=tab->index;
  tab->read_record.record=table->record[0];
unknown's avatar
unknown committed
9915 9916
  if (!table->file->inited)
    table->file->ha_index_init(tab->index);
9917 9918
  if ((error= tab->table->file->index_last(tab->table->record[0])))
    return report_error(table, error);
unknown's avatar
unknown committed
9919 9920 9921
  return 0;
}

9922

unknown's avatar
unknown committed
9923
static int
9924
join_read_prev(READ_RECORD *info)
unknown's avatar
unknown committed
9925
{
9926 9927 9928
  int error;
  if ((error= info->file->index_prev(info->record)))
    return report_error(info->table, error);
unknown's avatar
unknown committed
9929 9930 9931
  return 0;
}

9932

unknown's avatar
unknown committed
9933 9934 9935 9936 9937 9938
static int
join_ft_read_first(JOIN_TAB *tab)
{
  int error;
  TABLE *table= tab->table;

unknown's avatar
unknown committed
9939 9940
  if (!table->file->inited)
    table->file->ha_index_init(tab->ref.key);
unknown's avatar
unknown committed
9941
#if NOT_USED_YET
unknown's avatar
unknown committed
9942
  if (cp_buffer_from_ref(tab->join->thd, &tab->ref)) // as ft-key doesn't use store_key's
unknown's avatar
unknown committed
9943
    return -1;                             // see also FT_SELECT::init()
unknown's avatar
unknown committed
9944
#endif
9945
  table->file->ft_init();
unknown's avatar
unknown committed
9946

9947 9948
  if ((error= table->file->ft_read(table->record[0])))
    return report_error(table, error);
unknown's avatar
unknown committed
9949 9950 9951 9952 9953 9954
  return 0;
}

static int
join_ft_read_next(READ_RECORD *info)
{
9955 9956 9957
  int error;
  if ((error= info->file->ft_read(info->table->record[0])))
    return report_error(info->table, error);
unknown's avatar
unknown committed
9958 9959 9960 9961
  return 0;
}


9962 9963 9964 9965 9966 9967 9968 9969 9970 9971
/*
  Reading of key with key reference and one part that may be NULL
*/

static int
join_read_always_key_or_null(JOIN_TAB *tab)
{
  int res;

  /* First read according to key which is NOT NULL */
unknown's avatar
af  
unknown committed
9972
  *tab->ref.null_ref_key= 0;			// Clear null byte
9973 9974 9975 9976
  if ((res= join_read_always_key(tab)) >= 0)
    return res;

  /* Then read key with null value */
unknown's avatar
af  
unknown committed
9977
  *tab->ref.null_ref_key= 1;			// Set null byte
9978 9979 9980 9981 9982 9983 9984 9985 9986 9987 9988 9989 9990
  return safe_index_read(tab);
}


static int
join_read_next_same_or_null(READ_RECORD *info)
{
  int error;
  if ((error= join_read_next_same(info)) >= 0)
    return error;
  JOIN_TAB *tab= info->table->reginfo.join_tab;

  /* Test if we have already done a read after null key */
unknown's avatar
af  
unknown committed
9991
  if (*tab->ref.null_ref_key)
9992
    return -1;					// All keys read
unknown's avatar
af  
unknown committed
9993 9994
  *tab->ref.null_ref_key= 1;			// Set null byte
  return safe_index_read(tab);			// then read null keys
9995 9996 9997
}


unknown's avatar
unknown committed
9998
/*****************************************************************************
9999 10000 10001 10002 10003 10004 10005 10006 10007 10008 10009 10010 10011 10012 10013 10014 10015 10016 10017 10018 10019 10020
  DESCRIPTION
    Functions that end one nested loop iteration. Different functions
    are used to support GROUP BY clause and to redirect records
    to a table (e.g. in case of SELECT into a temporary table) or to the
    network client.

  RETURN VALUES
    NESTED_LOOP_OK           - the record has been successfully handled
    NESTED_LOOP_ERROR        - a fatal error (like table corruption)
                               was detected
    NESTED_LOOP_KILLED       - thread shutdown was requested while processing
                               the record
    NESTED_LOOP_QUERY_LIMIT  - the record has been successfully handled;
                               additionally, the nested loop produced the
                               number of rows specified in the LIMIT clause
                               for the query
    NESTED_LOOP_CURSOR_LIMIT - the record has been successfully handled;
                               additionally, there is a cursor and the nested
                               loop algorithm produced the number of rows
                               that is specified for current cursor fetch
                               operation.
   All return values except NESTED_LOOP_OK abort the nested loop.
unknown's avatar
unknown committed
10021 10022
*****************************************************************************/

10023
/* ARGSUSED */
10024
static enum_nested_loop_state
unknown's avatar
unknown committed
10025 10026 10027 10028 10029 10030 10031
end_send(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
	 bool end_of_records)
{
  DBUG_ENTER("end_send");
  if (!end_of_records)
  {
    int error;
10032
    if (join->having && join->having->val_int() == 0)
10033
      DBUG_RETURN(NESTED_LOOP_OK);               // Didn't match having
10034
    error=0;
unknown's avatar
unknown committed
10035 10036
    if (join->procedure)
      error=join->procedure->send_row(*join->fields);
unknown's avatar
unknown committed
10037
    else if (join->do_send_rows)
unknown's avatar
unknown committed
10038 10039
      error=join->result->send_data(*join->fields);
    if (error)
10040
      DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */
10041
    if (++join->send_records >= join->unit->select_limit_cnt &&
unknown's avatar
unknown committed
10042
	join->do_send_rows)
10043 10044 10045
    {
      if (join->select_options & OPTION_FOUND_ROWS)
      {
10046
	JOIN_TAB *jt=join->join_tab;
10047
	if ((join->tables == 1) && !join->tmp_table && !join->sort_and_group
10048
	    && !join->send_group_parts && !join->having && !jt->select_cond &&
10049
	    !(jt->select && jt->select->quick) &&
unknown's avatar
unknown committed
10050 10051
	    !(jt->table->file->table_flags() & HA_NOT_EXACT_COUNT) &&
            (jt->ref.key < 0))
10052
	{
10053
	  /* Join over all rows in table;  Return number of found rows */
10054 10055
	  TABLE *table=jt->table;

10056
	  join->select_options ^= OPTION_FOUND_ROWS;
unknown's avatar
unknown committed
10057 10058
	  if (table->sort.record_pointers ||
	      (table->sort.io_cache && my_b_inited(table->sort.io_cache)))
10059 10060
	  {
	    /* Using filesort */
unknown's avatar
unknown committed
10061
	    join->send_records= table->sort.found_records;
10062 10063 10064 10065 10066 10067
	  }
	  else
	  {
	    table->file->info(HA_STATUS_VARIABLE);
	    join->send_records = table->file->records;
	  }
10068 10069 10070
	}
	else 
	{
10071
	  join->do_send_rows= 0;
unknown's avatar
unknown committed
10072
	  if (join->unit->fake_select_lex)
10073
	    join->unit->fake_select_lex->select_limit= 0;
10074
	  DBUG_RETURN(NESTED_LOOP_OK);
10075
	}
10076
      }
10077
      DBUG_RETURN(NESTED_LOOP_QUERY_LIMIT);      // Abort nicely
10078
    }
10079 10080 10081 10082 10083 10084
    else if (join->send_records >= join->fetch_limit)
    {
      /*
        There is a server side cursor and all rows for
        this fetch request are sent.
      */
10085
      DBUG_RETURN(NESTED_LOOP_CURSOR_LIMIT);
10086
    }
unknown's avatar
unknown committed
10087 10088 10089 10090
  }
  else
  {
    if (join->procedure && join->procedure->end_of_records())
10091
      DBUG_RETURN(NESTED_LOOP_ERROR);
unknown's avatar
unknown committed
10092
  }
10093
  DBUG_RETURN(NESTED_LOOP_OK);
unknown's avatar
unknown committed
10094 10095 10096 10097
}


	/* ARGSUSED */
10098
static enum_nested_loop_state
unknown's avatar
unknown committed
10099 10100 10101 10102 10103 10104 10105 10106 10107 10108 10109 10110 10111 10112 10113
end_send_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
	       bool end_of_records)
{
  int idx= -1;
  DBUG_ENTER("end_send_group");

  if (!join->first_record || end_of_records ||
      (idx=test_if_group_changed(join->group_fields)) >= 0)
  {
    if (join->first_record || (end_of_records && !join->group))
    {
      if (join->procedure)
	join->procedure->end_group();
      if (idx < (int) join->send_group_parts)
      {
10114
	int error=0;
unknown's avatar
unknown committed
10115 10116
	if (join->procedure)
	{
10117
	  if (join->having && join->having->val_int() == 0)
unknown's avatar
unknown committed
10118
	    error= -1;				// Didn't satisfy having
10119 10120 10121 10122 10123 10124
 	  else
	  {
	    if (join->do_send_rows)
	      error=join->procedure->send_row(*join->fields) ? 1 : 0;
	    join->send_records++;
	  }
unknown's avatar
unknown committed
10125 10126 10127 10128 10129 10130
	  if (end_of_records && join->procedure->end_of_records())
	    error= 1;				// Fatal error
	}
	else
	{
	  if (!join->first_record)
10131 10132
	  {
	    /* No matching rows for group function */
10133
	    join->clear();
10134
	  }
10135
	  if (join->having && join->having->val_int() == 0)
unknown's avatar
unknown committed
10136
	    error= -1;				// Didn't satisfy having
10137 10138 10139 10140 10141 10142 10143 10144 10145 10146 10147
	  else
	  {
	    if (join->do_send_rows)
	      error=join->result->send_data(*join->fields) ? 1 : 0;
	    join->send_records++;
	  }
	  if (join->rollup.state != ROLLUP::STATE_NONE && error <= 0)
	  {
	    if (join->rollup_send_data((uint) (idx+1)))
	      error= 1;
	  }
unknown's avatar
unknown committed
10148 10149
	}
	if (error > 0)
10150
          DBUG_RETURN(NESTED_LOOP_ERROR);        /* purecov: inspected */
10151
	if (end_of_records)
10152
	  DBUG_RETURN(NESTED_LOOP_OK);
10153
	if (join->send_records >= join->unit->select_limit_cnt &&
10154 10155 10156
	    join->do_send_rows)
	{
	  if (!(join->select_options & OPTION_FOUND_ROWS))
10157
	    DBUG_RETURN(NESTED_LOOP_QUERY_LIMIT); // Abort nicely
10158
	  join->do_send_rows=0;
10159
	  join->unit->select_limit_cnt = HA_POS_ERROR;
10160
        }
10161 10162 10163 10164 10165 10166
        else if (join->send_records >= join->fetch_limit)
        {
          /*
            There is a server side cursor and all rows
            for this fetch request are sent.
          */
10167
          DBUG_RETURN(NESTED_LOOP_CURSOR_LIMIT);
10168
        }
unknown's avatar
unknown committed
10169 10170 10171 10172 10173
      }
    }
    else
    {
      if (end_of_records)
10174
	DBUG_RETURN(NESTED_LOOP_OK);
unknown's avatar
unknown committed
10175 10176 10177 10178 10179 10180
      join->first_record=1;
      VOID(test_if_group_changed(join->group_fields));
    }
    if (idx < (int) join->send_group_parts)
    {
      copy_fields(&join->tmp_table_param);
10181
      if (init_sum_functions(join->sum_funcs, join->sum_funcs_end[idx+1]))
10182
	DBUG_RETURN(NESTED_LOOP_ERROR);
unknown's avatar
unknown committed
10183 10184
      if (join->procedure)
	join->procedure->add();
10185
      DBUG_RETURN(NESTED_LOOP_OK);
unknown's avatar
unknown committed
10186 10187 10188
    }
  }
  if (update_sum_func(join->sum_funcs))
10189
    DBUG_RETURN(NESTED_LOOP_ERROR);
unknown's avatar
unknown committed
10190 10191
  if (join->procedure)
    join->procedure->add();
10192
  DBUG_RETURN(NESTED_LOOP_OK);
unknown's avatar
unknown committed
10193 10194 10195 10196
}


	/* ARGSUSED */
10197
static enum_nested_loop_state
unknown's avatar
unknown committed
10198 10199 10200 10201 10202 10203 10204 10205
end_write(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
	  bool end_of_records)
{
  TABLE *table=join->tmp_table;
  DBUG_ENTER("end_write");

  if (join->thd->killed)			// Aborted by user
  {
unknown's avatar
SCRUM  
unknown committed
10206
    join->thd->send_kill_message();
10207
    DBUG_RETURN(NESTED_LOOP_KILLED);             /* purecov: inspected */
unknown's avatar
unknown committed
10208 10209 10210 10211
  }
  if (!end_of_records)
  {
    copy_fields(&join->tmp_table_param);
unknown's avatar
unknown committed
10212
    copy_funcs(join->tmp_table_param.items_to_copy);
unknown's avatar
unknown committed
10213

10214
#ifdef TO_BE_DELETED
unknown's avatar
unknown committed
10215 10216 10217 10218 10219 10220 10221 10222 10223
    if (!table->uniques)			// If not unique handling
    {
      /* Copy null values from group to row */
      ORDER   *group;
      for (group=table->group ; group ; group=group->next)
      {
	Item *item= *group->item;
	if (item->maybe_null)
	{
10224
	  Field *field=item->get_tmp_table_field();
10225
	  field->ptr[-1]= (byte) (field->is_null() ? 1 : 0);
unknown's avatar
unknown committed
10226 10227 10228
	}
      }
    }
10229
#endif
unknown's avatar
unknown committed
10230 10231
    if (!join->having || join->having->val_int())
    {
10232
      int error;
unknown's avatar
unknown committed
10233
      join->found_records++;
unknown's avatar
unknown committed
10234 10235
      if ((error=table->file->write_row(table->record[0])))
      {
unknown's avatar
unknown committed
10236 10237 10238
	if (error == HA_ERR_FOUND_DUPP_KEY ||
	    error == HA_ERR_FOUND_DUPP_UNIQUE)
	  goto end;
unknown's avatar
unknown committed
10239 10240
	if (create_myisam_from_heap(join->thd, table, &join->tmp_table_param,
				    error,1))
10241
	  DBUG_RETURN(NESTED_LOOP_ERROR);        // Not a table_is_full error
10242
	table->s->uniques=0;			// To ensure rows are the same
10243
      }
unknown's avatar
unknown committed
10244
      if (++join->send_records >= join->tmp_table_param.end_write_records &&
10245 10246 10247
	  join->do_send_rows)
      {
	if (!(join->select_options & OPTION_FOUND_ROWS))
10248
	  DBUG_RETURN(NESTED_LOOP_QUERY_LIMIT);
10249
	join->do_send_rows=0;
10250
	join->unit->select_limit_cnt = HA_POS_ERROR;
10251
	DBUG_RETURN(NESTED_LOOP_OK);
unknown's avatar
unknown committed
10252 10253 10254
      }
    }
  }
unknown's avatar
unknown committed
10255
end:
10256
  DBUG_RETURN(NESTED_LOOP_OK);
unknown's avatar
unknown committed
10257 10258 10259 10260 10261
}

/* Group by searching after group record and updating it if possible */
/* ARGSUSED */

10262
static enum_nested_loop_state
unknown's avatar
unknown committed
10263 10264 10265 10266 10267 10268 10269 10270 10271
end_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
	   bool end_of_records)
{
  TABLE *table=join->tmp_table;
  ORDER   *group;
  int	  error;
  DBUG_ENTER("end_update");

  if (end_of_records)
10272
    DBUG_RETURN(NESTED_LOOP_OK);
unknown's avatar
unknown committed
10273 10274
  if (join->thd->killed)			// Aborted by user
  {
unknown's avatar
SCRUM  
unknown committed
10275
    join->thd->send_kill_message();
10276
    DBUG_RETURN(NESTED_LOOP_KILLED);             /* purecov: inspected */
unknown's avatar
unknown committed
10277 10278
  }

unknown's avatar
unknown committed
10279
  join->found_records++;
unknown's avatar
unknown committed
10280 10281 10282 10283 10284 10285
  copy_fields(&join->tmp_table_param);		// Groups are copied twice.
  /* Make a key of group index */
  for (group=table->group ; group ; group=group->next)
  {
    Item *item= *group->item;
    item->save_org_in_field(group->field);
10286
    /* Store in the used key if the field was 0 */
unknown's avatar
unknown committed
10287
    if (item->maybe_null)
10288
      group->buff[-1]=item->null_value ? 1 : 0;
unknown's avatar
unknown committed
10289 10290 10291 10292 10293
  }
  if (!table->file->index_read(table->record[1],
			       join->tmp_table_param.group_buff,0,
			       HA_READ_KEY_EXACT))
  {						/* Update old record */
unknown's avatar
unknown committed
10294
    restore_record(table,record[1]);
unknown's avatar
unknown committed
10295 10296 10297 10298 10299
    update_tmptable_sum_func(join->sum_funcs,table);
    if ((error=table->file->update_row(table->record[1],
				       table->record[0])))
    {
      table->file->print_error(error,MYF(0));	/* purecov: inspected */
10300
      DBUG_RETURN(NESTED_LOOP_ERROR);            /* purecov: inspected */
unknown's avatar
unknown committed
10301
    }
10302
    DBUG_RETURN(NESTED_LOOP_OK);
unknown's avatar
unknown committed
10303 10304
  }

10305 10306 10307 10308 10309
  /*
    Copy null bits from group key to table
    We can't copy all data as the key may have different format
    as the row data (for example as with VARCHAR keys)
  */
unknown's avatar
unknown committed
10310 10311 10312 10313
  KEY_PART_INFO *key_part;
  for (group=table->group,key_part=table->key_info[0].key_part;
       group ;
       group=group->next,key_part++)
10314 10315 10316 10317
  {
    if (key_part->null_bit)
      memcpy(table->record[0]+key_part->offset, group->buff, 1);
  }
unknown's avatar
unknown committed
10318
  init_tmptable_sum_functions(join->sum_funcs);
unknown's avatar
unknown committed
10319
  copy_funcs(join->tmp_table_param.items_to_copy);
unknown's avatar
unknown committed
10320 10321
  if ((error=table->file->write_row(table->record[0])))
  {
unknown's avatar
unknown committed
10322 10323
    if (create_myisam_from_heap(join->thd, table, &join->tmp_table_param,
				error, 0))
10324
      DBUG_RETURN(NESTED_LOOP_ERROR);            // Not a table_is_full error
unknown's avatar
unknown committed
10325
    /* Change method to update rows */
unknown's avatar
unknown committed
10326
    table->file->ha_index_init(0);
unknown's avatar
unknown committed
10327 10328 10329
    join->join_tab[join->tables-1].next_select=end_unique_update;
  }
  join->send_records++;
10330
  DBUG_RETURN(NESTED_LOOP_OK);
unknown's avatar
unknown committed
10331 10332
}

10333

unknown's avatar
unknown committed
10334 10335
/* Like end_update, but this is done with unique constraints instead of keys */

10336
static enum_nested_loop_state
unknown's avatar
unknown committed
10337 10338 10339 10340 10341 10342 10343 10344
end_unique_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
		  bool end_of_records)
{
  TABLE *table=join->tmp_table;
  int	  error;
  DBUG_ENTER("end_unique_update");

  if (end_of_records)
10345
    DBUG_RETURN(NESTED_LOOP_OK);
unknown's avatar
unknown committed
10346 10347
  if (join->thd->killed)			// Aborted by user
  {
unknown's avatar
SCRUM  
unknown committed
10348
    join->thd->send_kill_message();
10349
    DBUG_RETURN(NESTED_LOOP_KILLED);             /* purecov: inspected */
unknown's avatar
unknown committed
10350 10351 10352 10353
  }

  init_tmptable_sum_functions(join->sum_funcs);
  copy_fields(&join->tmp_table_param);		// Groups are copied twice.
unknown's avatar
unknown committed
10354
  copy_funcs(join->tmp_table_param.items_to_copy);
unknown's avatar
unknown committed
10355 10356 10357 10358 10359 10360 10361 10362

  if (!(error=table->file->write_row(table->record[0])))
    join->send_records++;			// New group
  else
  {
    if ((int) table->file->get_dup_key(error) < 0)
    {
      table->file->print_error(error,MYF(0));	/* purecov: inspected */
10363
      DBUG_RETURN(NESTED_LOOP_ERROR);            /* purecov: inspected */
unknown's avatar
unknown committed
10364 10365 10366 10367
    }
    if (table->file->rnd_pos(table->record[1],table->file->dupp_ref))
    {
      table->file->print_error(error,MYF(0));	/* purecov: inspected */
10368
      DBUG_RETURN(NESTED_LOOP_ERROR);            /* purecov: inspected */
unknown's avatar
unknown committed
10369
    }
unknown's avatar
unknown committed
10370
    restore_record(table,record[1]);
unknown's avatar
unknown committed
10371 10372 10373 10374 10375
    update_tmptable_sum_func(join->sum_funcs,table);
    if ((error=table->file->update_row(table->record[1],
				       table->record[0])))
    {
      table->file->print_error(error,MYF(0));	/* purecov: inspected */
10376
      DBUG_RETURN(NESTED_LOOP_ERROR);            /* purecov: inspected */
unknown's avatar
unknown committed
10377 10378
    }
  }
10379
  DBUG_RETURN(NESTED_LOOP_OK);
unknown's avatar
unknown committed
10380 10381 10382 10383
}


	/* ARGSUSED */
10384
static enum_nested_loop_state
unknown's avatar
unknown committed
10385 10386 10387 10388 10389 10390 10391 10392 10393
end_write_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
		bool end_of_records)
{
  TABLE *table=join->tmp_table;
  int	  idx= -1;
  DBUG_ENTER("end_write_group");

  if (join->thd->killed)
  {						// Aborted by user
unknown's avatar
SCRUM  
unknown committed
10394
    join->thd->send_kill_message();
10395
    DBUG_RETURN(NESTED_LOOP_KILLED);             /* purecov: inspected */
unknown's avatar
unknown committed
10396 10397 10398 10399 10400 10401 10402 10403
  }
  if (!join->first_record || end_of_records ||
      (idx=test_if_group_changed(join->group_fields)) >= 0)
  {
    if (join->first_record || (end_of_records && !join->group))
    {
      if (join->procedure)
	join->procedure->end_group();
unknown's avatar
unknown committed
10404 10405
      int send_group_parts= join->send_group_parts;
      if (idx < send_group_parts)
unknown's avatar
unknown committed
10406 10407
      {
	if (!join->first_record)
10408 10409
	{
	  /* No matching rows for group function */
10410
	  join->clear();
10411
	}
unknown's avatar
unknown committed
10412 10413
        copy_sum_funcs(join->sum_funcs,
                       join->sum_funcs_end[send_group_parts]);
10414
	if (!join->having || join->having->val_int())
unknown's avatar
unknown committed
10415
	{
10416 10417 10418 10419 10420
          int error= table->file->write_row(table->record[0]);
          if (error && create_myisam_from_heap(join->thd, table,
                                               &join->tmp_table_param,
                                               error, 0))
	    DBUG_RETURN(NESTED_LOOP_ERROR);
unknown's avatar
unknown committed
10421
        }
unknown's avatar
unknown committed
10422
        if (join->rollup.state != ROLLUP::STATE_NONE)
unknown's avatar
unknown committed
10423 10424
	{
	  if (join->rollup_write_data((uint) (idx+1), table))
10425
	    DBUG_RETURN(NESTED_LOOP_ERROR);
unknown's avatar
unknown committed
10426 10427
	}
	if (end_of_records)
10428
	  DBUG_RETURN(NESTED_LOOP_OK);
unknown's avatar
unknown committed
10429 10430 10431 10432
      }
    }
    else
    {
10433
      if (end_of_records)
10434
	DBUG_RETURN(NESTED_LOOP_OK);
unknown's avatar
unknown committed
10435 10436 10437 10438 10439 10440
      join->first_record=1;
      VOID(test_if_group_changed(join->group_fields));
    }
    if (idx < (int) join->send_group_parts)
    {
      copy_fields(&join->tmp_table_param);
unknown's avatar
unknown committed
10441
      copy_funcs(join->tmp_table_param.items_to_copy);
10442
      if (init_sum_functions(join->sum_funcs, join->sum_funcs_end[idx+1]))
10443
	DBUG_RETURN(NESTED_LOOP_ERROR);
unknown's avatar
unknown committed
10444 10445
      if (join->procedure)
	join->procedure->add();
10446
      DBUG_RETURN(NESTED_LOOP_OK);
unknown's avatar
unknown committed
10447 10448 10449
    }
  }
  if (update_sum_func(join->sum_funcs))
10450
    DBUG_RETURN(NESTED_LOOP_ERROR);
unknown's avatar
unknown committed
10451 10452
  if (join->procedure)
    join->procedure->add();
10453
  DBUG_RETURN(NESTED_LOOP_OK);
unknown's avatar
unknown committed
10454 10455 10456 10457
}


/*****************************************************************************
10458 10459 10460 10461 10462
  Remove calculation with tables that aren't yet read. Remove also tests
  against fields that are read through key where the table is not a
  outer join table.
  We can't remove tests that are made against columns which are stored
  in sorted order.
unknown's avatar
unknown committed
10463 10464 10465 10466 10467 10468 10469
*****************************************************************************/

/* Return 1 if right_item is used removable reference key on left_item */

static bool test_if_ref(Item_field *left_item,Item *right_item)
{
  Field *field=left_item->field;
10470 10471
  // No need to change const test. We also have to keep tests on LEFT JOIN
  if (!field->table->const_table && !field->table->maybe_null)
unknown's avatar
unknown committed
10472 10473
  {
    Item *ref_item=part_of_refkey(field->table,field);
10474
    if (ref_item && ref_item->eq(right_item,1))
unknown's avatar
unknown committed
10475 10476
    {
      if (right_item->type() == Item::FIELD_ITEM)
10477 10478
	return (field->eq_def(((Item_field *) right_item)->field));
      if (right_item->const_item() && !(right_item->is_null()))
unknown's avatar
unknown committed
10479
      {
10480 10481 10482
	/*
	  We can remove binary fields and numerical fields except float,
	  as float comparison isn't 100 % secure
10483
	  We have to keep normal strings to be able to check for end spaces
10484
	*/
unknown's avatar
unknown committed
10485
	if (field->binary() &&
10486 10487
	    field->real_type() != MYSQL_TYPE_STRING &&
	    field->real_type() != MYSQL_TYPE_VARCHAR &&
unknown's avatar
unknown committed
10488 10489 10490 10491 10492 10493 10494 10495 10496 10497 10498 10499
	    (field->type() != FIELD_TYPE_FLOAT || field->decimals() == 0))
	{
	  return !store_val_in_field(field,right_item);
	}
      }
    }
  }
  return 0;					// keep test
}


static COND *
unknown's avatar
af  
unknown committed
10500
make_cond_for_table(COND *cond, table_map tables, table_map used_table)
unknown's avatar
unknown committed
10501 10502 10503 10504 10505 10506 10507
{
  if (used_table && !(cond->used_tables() & used_table))
    return (COND*) 0;				// Already checked
  if (cond->type() == Item::COND_ITEM)
  {
    if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
    {
10508
      /* Create new top level AND item */
unknown's avatar
unknown committed
10509 10510 10511 10512 10513 10514 10515 10516 10517 10518 10519 10520 10521 10522 10523 10524 10525
      Item_cond_and *new_cond=new Item_cond_and;
      if (!new_cond)
	return (COND*) 0;			// OOM /* purecov: inspected */
      List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
      Item *item;
      while ((item=li++))
      {
	Item *fix=make_cond_for_table(item,tables,used_table);
	if (fix)
	  new_cond->argument_list()->push_back(fix);
      }
      switch (new_cond->argument_list()->elements) {
      case 0:
	return (COND*) 0;			// Always true
      case 1:
	return new_cond->argument_list()->head();
      default:
unknown's avatar
af  
unknown committed
10526 10527 10528 10529 10530 10531 10532
	/*
	  Item_cond_and do not need fix_fields for execution, its parameters
	  are fixed or do not need fix_fields, too
	*/
	new_cond->quick_fix_field();
	new_cond->used_tables_cache=
	  ((Item_cond_and*) cond)->used_tables_cache &
unknown's avatar
unknown committed
10533 10534 10535 10536 10537 10538 10539 10540 10541 10542 10543 10544 10545 10546 10547 10548 10549 10550
	  tables;
	return new_cond;
      }
    }
    else
    {						// Or list
      Item_cond_or *new_cond=new Item_cond_or;
      if (!new_cond)
	return (COND*) 0;			// OOM /* purecov: inspected */
      List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
      Item *item;
      while ((item=li++))
      {
	Item *fix=make_cond_for_table(item,tables,0L);
	if (!fix)
	  return (COND*) 0;			// Always true
	new_cond->argument_list()->push_back(fix);
      }
unknown's avatar
af  
unknown committed
10551 10552 10553 10554 10555 10556
      /*
	Item_cond_and do not need fix_fields for execution, its parameters
	are fixed or do not need fix_fields, too
      */
      new_cond->quick_fix_field();
      new_cond->used_tables_cache= ((Item_cond_or*) cond)->used_tables_cache;
10557
      new_cond->top_level_item();
unknown's avatar
unknown committed
10558 10559 10560 10561 10562
      return new_cond;
    }
  }

  /*
10563 10564 10565
    Because the following test takes a while and it can be done
    table_count times, we mark each item that we have examined with the result
    of the test
unknown's avatar
unknown committed
10566 10567 10568 10569 10570 10571 10572 10573 10574 10575 10576 10577 10578 10579 10580 10581 10582 10583 10584 10585 10586 10587 10588 10589 10590 10591 10592 10593 10594 10595 10596
  */

  if (cond->marker == 3 || (cond->used_tables() & ~tables))
    return (COND*) 0;				// Can't check this yet
  if (cond->marker == 2 || cond->eq_cmp_result() == Item::COND_OK)
    return cond;				// Not boolean op

  if (((Item_func*) cond)->functype() == Item_func::EQ_FUNC)
  {
    Item *left_item=	((Item_func*) cond)->arguments()[0];
    Item *right_item= ((Item_func*) cond)->arguments()[1];
    if (left_item->type() == Item::FIELD_ITEM &&
	test_if_ref((Item_field*) left_item,right_item))
    {
      cond->marker=3;			// Checked when read
      return (COND*) 0;
    }
    if (right_item->type() == Item::FIELD_ITEM &&
	test_if_ref((Item_field*) right_item,left_item))
    {
      cond->marker=3;			// Checked when read
      return (COND*) 0;
    }
  }
  cond->marker=2;
  return cond;
}

static Item *
part_of_refkey(TABLE *table,Field *field)
{
10597 10598 10599
  if (!table->reginfo.join_tab)
    return (Item*) 0;             // field from outer non-select (UPDATE,...)

unknown's avatar
unknown committed
10600 10601 10602 10603 10604 10605 10606 10607
  uint ref_parts=table->reginfo.join_tab->ref.key_parts;
  if (ref_parts)
  {
    KEY_PART_INFO *key_part=
      table->key_info[table->reginfo.join_tab->ref.key].key_part;

    for (uint part=0 ; part < ref_parts ; part++,key_part++)
      if (field->eq(key_part->field) &&
10608
	  !(key_part->key_part_flag & HA_PART_KEY_SEG))
unknown's avatar
unknown committed
10609 10610 10611 10612 10613 10614 10615
	return table->reginfo.join_tab->ref.items[part];
  }
  return (Item*) 0;
}


/*****************************************************************************
10616
  Test if one can use the key to resolve ORDER BY
10617 10618 10619 10620 10621 10622 10623 10624 10625 10626 10627 10628 10629 10630 10631 10632 10633

  SYNOPSIS
    test_if_order_by_key()
    order		Sort order
    table		Table to sort
    idx			Index to check
    used_key_parts	Return value for used key parts.


  NOTES
    used_key_parts is set to correct key parts used if return value != 0
    (On other cases, used_key_part may be changed)

  RETURN
    1   key is ok.
    0   Key can't be used
    -1  Reverse key can be used
unknown's avatar
unknown committed
10634 10635
*****************************************************************************/

unknown's avatar
unknown committed
10636 10637
static int test_if_order_by_key(ORDER *order, TABLE *table, uint idx,
				uint *used_key_parts)
unknown's avatar
unknown committed
10638 10639 10640 10641 10642 10643
{
  KEY_PART_INFO *key_part,*key_part_end;
  key_part=table->key_info[idx].key_part;
  key_part_end=key_part+table->key_info[idx].key_parts;
  key_part_map const_key_parts=table->const_key_parts[idx];
  int reverse=0;
unknown's avatar
af  
unknown committed
10644
  DBUG_ENTER("test_if_order_by_key");
unknown's avatar
unknown committed
10645 10646 10647 10648 10649 10650 10651 10652 10653 10654

  for (; order ; order=order->next, const_key_parts>>=1)
  {
    Field *field=((Item_field*) (*order->item))->field;
    int flag;

    /*
      Skip key parts that are constants in the WHERE clause.
      These are already skipped in the ORDER BY by const_expression_in_where()
    */
unknown's avatar
af  
unknown committed
10655 10656 10657
    for (; const_key_parts & 1 ; const_key_parts>>= 1)
      key_part++; 

unknown's avatar
unknown committed
10658
    if (key_part == key_part_end || key_part->field != field)
unknown's avatar
af  
unknown committed
10659
      DBUG_RETURN(0);
unknown's avatar
unknown committed
10660 10661

    /* set flag to 1 if we can use read-next on key, else to -1 */
10662 10663
    flag= ((order->asc == !(key_part->key_part_flag & HA_REVERSE_SORT)) ?
           1 : -1);
unknown's avatar
unknown committed
10664
    if (reverse && flag != reverse)
unknown's avatar
af  
unknown committed
10665
      DBUG_RETURN(0);
unknown's avatar
unknown committed
10666 10667 10668
    reverse=flag;				// Remember if reverse
    key_part++;
  }
unknown's avatar
unknown committed
10669
  *used_key_parts= (uint) (key_part - table->key_info[idx].key_part);
10670 10671 10672
  if (reverse == -1 && !(table->file->index_flags(idx, *used_key_parts-1, 1) &
                         HA_READ_PREV))
    reverse= 0;                                 // Index can't be used
unknown's avatar
af  
unknown committed
10673
  DBUG_RETURN(reverse);
unknown's avatar
unknown committed
10674 10675
}

unknown's avatar
af  
unknown committed
10676

10677
uint find_shortest_key(TABLE *table, const key_map *usable_keys)
unknown's avatar
unknown committed
10678 10679 10680
{
  uint min_length= (uint) ~0;
  uint best= MAX_KEY;
unknown's avatar
unknown committed
10681
  if (!usable_keys->is_clear_all())
unknown's avatar
unknown committed
10682
  {
10683
    for (uint nr=0; nr < table->s->keys ; nr++)
unknown's avatar
unknown committed
10684
    {
unknown's avatar
unknown committed
10685
      if (usable_keys->is_set(nr))
unknown's avatar
unknown committed
10686
      {
10687 10688 10689 10690 10691
        if (table->key_info[nr].key_length < min_length)
        {
          min_length=table->key_info[nr].key_length;
          best=nr;
        }
unknown's avatar
unknown committed
10692 10693 10694 10695 10696 10697
      }
    }
  }
  return best;
}

10698
/*
unknown's avatar
af  
unknown committed
10699 10700
  Test if a second key is the subkey of the first one.

10701 10702
  SYNOPSIS
    is_subkey()
unknown's avatar
af  
unknown committed
10703 10704 10705 10706
    key_part		First key parts
    ref_key_part	Second key parts
    ref_key_part_end	Last+1 part of the second key

10707 10708
  NOTE
    Second key MUST be shorter than the first one.
unknown's avatar
af  
unknown committed
10709

10710
  RETURN
unknown's avatar
af  
unknown committed
10711 10712
    1	is a subkey
    0	no sub key
10713 10714 10715 10716 10717 10718 10719 10720 10721 10722 10723 10724 10725
*/

inline bool 
is_subkey(KEY_PART_INFO *key_part, KEY_PART_INFO *ref_key_part,
	  KEY_PART_INFO *ref_key_part_end)
{
  for (; ref_key_part < ref_key_part_end; key_part++, ref_key_part++)
    if (!key_part->field->eq(ref_key_part->field))
      return 0;
  return 1;
}

/*
unknown's avatar
af  
unknown committed
10726 10727
  Test if we can use one of the 'usable_keys' instead of 'ref' key for sorting

10728 10729
  SYNOPSIS
    test_if_subkey()
unknown's avatar
af  
unknown committed
10730 10731 10732
    ref			Number of key, used for WHERE clause
    usable_keys		Keys for testing

10733
  RETURN
unknown's avatar
af  
unknown committed
10734 10735
    MAX_KEY			If we can't use other key
    the number of found key	Otherwise
10736 10737 10738
*/

static uint
unknown's avatar
unknown committed
10739
test_if_subkey(ORDER *order, TABLE *table, uint ref, uint ref_key_parts,
unknown's avatar
af  
unknown committed
10740
	       const key_map *usable_keys)
10741 10742 10743 10744 10745 10746 10747
{
  uint nr;
  uint min_length= (uint) ~0;
  uint best= MAX_KEY;
  uint not_used;
  KEY_PART_INFO *ref_key_part= table->key_info[ref].key_part;
  KEY_PART_INFO *ref_key_part_end= ref_key_part + ref_key_parts;
10748

10749
  for (nr= 0 ; nr < table->s->keys ; nr++)
10750
  {
unknown's avatar
af  
unknown committed
10751
    if (usable_keys->is_set(nr) &&
10752 10753 10754 10755 10756 10757 10758 10759 10760 10761 10762 10763
	table->key_info[nr].key_length < min_length &&
	table->key_info[nr].key_parts >= ref_key_parts &&
	is_subkey(table->key_info[nr].key_part, ref_key_part,
		  ref_key_part_end) &&
	test_if_order_by_key(order, table, nr, &not_used))
    {
      min_length= table->key_info[nr].key_length;
      best= nr;
    }
  }
  return best;
}
unknown's avatar
unknown committed
10764

10765 10766 10767 10768 10769 10770 10771 10772 10773 10774
/*
  Test if we can skip the ORDER BY by using an index.

  If we can use an index, the JOIN_TAB / tab->select struct
  is changed to use the index.

  Return:
     0 We have to use filesort to do the sorting
     1 We can use an index.
*/
unknown's avatar
unknown committed
10775 10776

static bool
10777 10778
test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
			bool no_changes)
unknown's avatar
unknown committed
10779 10780
{
  int ref_key;
unknown's avatar
unknown committed
10781
  uint ref_key_parts;
unknown's avatar
unknown committed
10782 10783 10784 10785
  TABLE *table=tab->table;
  SQL_SELECT *select=tab->select;
  key_map usable_keys;
  DBUG_ENTER("test_if_skip_sort_order");
unknown's avatar
unknown committed
10786
  LINT_INIT(ref_key_parts);
unknown's avatar
unknown committed
10787 10788

  /* Check which keys can be used to resolve ORDER BY */
10789
  usable_keys.set_all();
unknown's avatar
unknown committed
10790 10791 10792 10793
  for (ORDER *tmp_order=order; tmp_order ; tmp_order=tmp_order->next)
  {
    if ((*tmp_order->item)->type() != Item::FIELD_ITEM)
    {
10794
      usable_keys.clear_all();
unknown's avatar
af  
unknown committed
10795
      DBUG_RETURN(0);
unknown's avatar
unknown committed
10796
    }
unknown's avatar
af  
unknown committed
10797 10798
    usable_keys.intersect(((Item_field*) (*tmp_order->item))->
			  field->part_of_sortkey);
unknown's avatar
unknown committed
10799
    if (usable_keys.is_clear_all())
unknown's avatar
af  
unknown committed
10800
      DBUG_RETURN(0);					// No usable keys
unknown's avatar
unknown committed
10801 10802 10803
  }

  ref_key= -1;
10804
  /* Test if constant range in WHERE */
unknown's avatar
af  
unknown committed
10805
  if (tab->ref.key >= 0 && tab->ref.key_parts)
unknown's avatar
unknown committed
10806 10807 10808
  {
    ref_key=	   tab->ref.key;
    ref_key_parts= tab->ref.key_parts;
10809
    if (tab->type == JT_REF_OR_NULL || tab->type == JT_FT)
10810
      DBUG_RETURN(0);
unknown's avatar
unknown committed
10811
  }
unknown's avatar
unknown committed
10812
  else if (select && select->quick)		// Range found by opt_range
unknown's avatar
unknown committed
10813
  {
unknown's avatar
af  
unknown committed
10814 10815 10816 10817 10818 10819 10820 10821 10822 10823
    int quick_type= select->quick->get_type();
    /* 
      assume results are not ordered when index merge is used 
      TODO: sergeyp: Results of all index merge selects actually are ordered 
      by clustered PK values.
    */
  
    if (quick_type == QUICK_SELECT_I::QS_TYPE_INDEX_MERGE || 
        quick_type == QUICK_SELECT_I::QS_TYPE_ROR_UNION || 
        quick_type == QUICK_SELECT_I::QS_TYPE_ROR_INTERSECT)
unknown's avatar
unknown committed
10824
      DBUG_RETURN(0);
unknown's avatar
unknown committed
10825 10826 10827
    ref_key=	   select->quick->index;
    ref_key_parts= select->quick->used_key_parts;
  }
unknown's avatar
unknown committed
10828 10829 10830

  if (ref_key >= 0)
  {
10831 10832 10833
    /*
      We come here when there is a REF key.
    */
10834
    int order_direction;
unknown's avatar
unknown committed
10835
    uint used_key_parts;
10836
    if (!usable_keys.is_set(ref_key))
10837 10838 10839 10840
    {
      /*
	We come here when ref_key is not among usable_keys
      */
unknown's avatar
unknown committed
10841 10842 10843 10844 10845
      uint new_ref_key;
      /*
	If using index only read, only consider other possible index only
	keys
      */
10846
      if (table->used_keys.is_set(ref_key))
unknown's avatar
af  
unknown committed
10847
	usable_keys.intersect(table->used_keys);
unknown's avatar
unknown committed
10848
      if ((new_ref_key= test_if_subkey(order, table, ref_key, ref_key_parts,
unknown's avatar
af  
unknown committed
10849
				       &usable_keys)) < MAX_KEY)
10850
      {
unknown's avatar
unknown committed
10851
	/* Found key that can be used to retrieve data in sorted order */
10852 10853
	if (tab->ref.key >= 0)
	{
10854 10855 10856
          /*
            We'll use ref access method on key new_ref_key. In general case 
            the index search tuple for new_ref_key will be different (e.g.
unknown's avatar
unknown committed
10857 10858 10859
            when one index is defined as (part1, part2, ...) and another as
            (part1, part2(N), ...) and the WHERE clause contains 
            "part1 = const1 AND part2=const2". 
10860 10861 10862 10863 10864 10865 10866 10867
            So we build tab->ref from scratch here.
          */
          KEYUSE *keyuse= tab->keyuse;
          while (keyuse->key != new_ref_key && keyuse->table == tab->table)
            keyuse++;
          if (create_ref_for_key(tab->join, tab, keyuse, 
                                 tab->join->const_table_map))
            DBUG_RETURN(0);
10868 10869 10870
	}
	else
	{
10871 10872 10873 10874 10875 10876 10877 10878 10879
          /*
            The range optimizer constructed QUICK_RANGE for ref_key, and
            we want to use instead new_ref_key as the index. We can't
            just change the index of the quick select, because this may
            result in an incosistent QUICK_SELECT object. Below we
            create a new QUICK_SELECT from scratch so that all its
            parameres are set correctly by the range optimizer.
           */
          key_map new_ref_key_map;
10880 10881
          new_ref_key_map.clear_all();  // Force the creation of quick select
          new_ref_key_map.set_bit(new_ref_key); // only for new_ref_key.
10882 10883

          if (select->test_quick_select(tab->join->thd, new_ref_key_map, 0,
10884 10885 10886 10887 10888
                                        (tab->join->select_options &
                                         OPTION_FOUND_ROWS) ?
                                        HA_POS_ERROR :
                                        tab->join->unit->select_limit_cnt,0) <=
              0)
10889
            DBUG_RETURN(0);
10890
	}
unknown's avatar
unknown committed
10891
        ref_key= new_ref_key;
10892
      }
10893
    }
unknown's avatar
unknown committed
10894
    /* Check if we get the rows in requested sorted order by using the key */
10895
    if (usable_keys.is_set(ref_key) &&
unknown's avatar
unknown committed
10896 10897
	(order_direction = test_if_order_by_key(order,table,ref_key,
						&used_key_parts)))
10898
    {
10899
      if (order_direction == -1)		// If ORDER BY ... DESC
10900
      {
unknown's avatar
unknown committed
10901 10902
	if (select && select->quick)
	{
10903 10904 10905 10906 10907
	  /*
	    Don't reverse the sort order, if it's already done.
	    (In some cases test_if_order_by_key() can be called multiple times
	  */
	  if (!select->quick->reverse_sorted())
unknown's avatar
unknown committed
10908
	  {
unknown's avatar
af  
unknown committed
10909
            int quick_type= select->quick->get_type();
unknown's avatar
unknown committed
10910
            if (quick_type == QUICK_SELECT_I::QS_TYPE_INDEX_MERGE ||
unknown's avatar
af  
unknown committed
10911
                quick_type == QUICK_SELECT_I::QS_TYPE_ROR_INTERSECT ||
10912 10913
                quick_type == QUICK_SELECT_I::QS_TYPE_ROR_UNION ||
                quick_type == QUICK_SELECT_I::QS_TYPE_GROUP_MIN_MAX)
unknown's avatar
unknown committed
10914
              DBUG_RETURN(0);                   // Use filesort
unknown's avatar
unknown committed
10915
            
unknown's avatar
unknown committed
10916
            /* ORDER BY range_key DESC */
unknown's avatar
unknown committed
10917
	    QUICK_SELECT_DESC *tmp=new QUICK_SELECT_DESC((QUICK_RANGE_SELECT*)(select->quick),
10918 10919 10920 10921 10922 10923 10924
							 used_key_parts);
	    if (!tmp || tmp->error)
	    {
	      delete tmp;
	      DBUG_RETURN(0);		// Reverse sort not supported
	    }
	    select->quick=tmp;
unknown's avatar
unknown committed
10925 10926 10927 10928 10929 10930 10931
	  }
	  DBUG_RETURN(1);
	}
	if (tab->ref.key_parts < used_key_parts)
	{
	  /*
	    SELECT * FROM t1 WHERE a=1 ORDER BY a DESC,b DESC
10932 10933 10934

	    Use a traversal function that starts by reading the last row
	    with key part (A) and then traverse the index backwards.
unknown's avatar
unknown committed
10935
	  */
10936 10937 10938
	  tab->read_first_record=       join_read_last_key;
	  tab->read_record.read_record= join_read_prev_same;
	  /* fall through */
unknown's avatar
unknown committed
10939
	}
10940
      }
unknown's avatar
af  
unknown committed
10941 10942
      else if (select && select->quick)
	  select->quick->sorted= 1;
unknown's avatar
unknown committed
10943
      DBUG_RETURN(1);			/* No need to sort */
10944
    }
unknown's avatar
unknown committed
10945 10946 10947 10948 10949 10950
  }
  else
  {
    /* check if we can use a key to resolve the group */
    /* Tables using JT_NEXT are handled here */
    uint nr;
10951
    key_map keys;
unknown's avatar
unknown committed
10952 10953 10954 10955 10956 10957 10958

    /*
      If not used with LIMIT, only use keys if the whole query can be
      resolved with a key;  This is because filesort() is usually faster than
      retrieving all rows through an index.
    */
    if (select_limit >= table->file->records)
10959
    {
unknown's avatar
af  
unknown committed
10960
      keys= *table->file->keys_to_use_for_scanning();
10961
      keys.merge(table->used_keys);
unknown's avatar
af  
unknown committed
10962 10963

      /*
10964
	We are adding here also the index specified in FORCE INDEX clause, 
unknown's avatar
af  
unknown committed
10965
	if any.
10966
        This is to allow users to use index in ORDER BY.
unknown's avatar
af  
unknown committed
10967 10968 10969 10970
      */
      if (table->force_index) 
	keys.merge(table->keys_in_use_for_query);
      keys.intersect(usable_keys);
10971 10972
    }
    else
unknown's avatar
af  
unknown committed
10973
      keys= usable_keys;
unknown's avatar
unknown committed
10974

10975
    for (nr=0; nr < table->s->keys ; nr++)
unknown's avatar
unknown committed
10976
    {
unknown's avatar
unknown committed
10977
      uint not_used;
10978
      if (keys.is_set(nr))
unknown's avatar
unknown committed
10979 10980
      {
	int flag;
unknown's avatar
unknown committed
10981
	if ((flag= test_if_order_by_key(order, table, nr, &not_used)))
unknown's avatar
unknown committed
10982
	{
10983 10984 10985
	  if (!no_changes)
	  {
	    tab->index=nr;
10986 10987
	    tab->read_first_record=  (flag > 0 ? join_read_first:
				      join_read_last);
10988
	    tab->type=JT_NEXT;	// Read with index_first(), index_next()
10989
	    if (table->used_keys.is_set(nr))
unknown's avatar
unknown committed
10990 10991 10992 10993
	    {
	      table->key_read=1;
	      table->file->extra(HA_EXTRA_KEYREAD);
	    }
10994
	  }
unknown's avatar
unknown committed
10995 10996 10997 10998 10999 11000 11001 11002
	  DBUG_RETURN(1);
	}
      }
    }
  }
  DBUG_RETURN(0);				// Can't use index.
}

unknown's avatar
unknown committed
11003

unknown's avatar
unknown committed
11004
/*
unknown's avatar
unknown committed
11005
  If not selecting by given key, create an index how records should be read
unknown's avatar
unknown committed
11006 11007 11008 11009 11010 11011 11012 11013

  SYNOPSIS
   create_sort_index()
     thd		Thread handler
     tab		Table to sort (in join structure)
     order		How table should be sorted
     filesort_limit	Max number of rows that needs to be sorted
     select_limit	Max number of rows in final output
11014
		        Used to decide if we should use index or not
unknown's avatar
unknown committed
11015 11016 11017 11018 11019 11020 11021 11022 11023 11024 11025 11026 11027 11028 11029


  IMPLEMENTATION
   - If there is an index that can be used, 'tab' is modified to use
     this index.
   - If no index, create with filesort() an index file that can be used to
     retrieve rows in order (should be done with 'read_record').
     The sorted data is stored in tab->table and will be freed when calling
     free_io_cache(tab->table).

  RETURN VALUES
    0		ok
    -1		Some fatal error
    1		No records
*/
unknown's avatar
unknown committed
11030

unknown's avatar
unknown committed
11031
static int
11032
create_sort_index(THD *thd, JOIN *join, ORDER *order,
unknown's avatar
unknown committed
11033
		  ha_rows filesort_limit, ha_rows select_limit)
unknown's avatar
unknown committed
11034 11035 11036
{
  SORT_FIELD *sortorder;
  uint length;
11037
  ha_rows examined_rows;
11038 11039 11040
  TABLE *table;
  SQL_SELECT *select;
  JOIN_TAB *tab;
unknown's avatar
unknown committed
11041 11042
  DBUG_ENTER("create_sort_index");

11043 11044 11045 11046 11047 11048
  if (join->tables == join->const_tables)
    DBUG_RETURN(0);				// One row, no need to sort
  tab=    join->join_tab + join->const_tables;
  table=  tab->table;
  select= tab->select;

11049
  if (test_if_skip_sort_order(tab,order,select_limit,0))
unknown's avatar
unknown committed
11050 11051 11052 11053
    DBUG_RETURN(0);
  if (!(sortorder=make_unireg_sortorder(order,&length)))
    goto err;				/* purecov: inspected */
  /* It's not fatal if the following alloc fails */
unknown's avatar
unknown committed
11054 11055
  table->sort.io_cache=(IO_CACHE*) my_malloc(sizeof(IO_CACHE),
                                             MYF(MY_WME | MY_ZEROFILL));
unknown's avatar
unknown committed
11056 11057 11058 11059 11060 11061 11062 11063 11064
  table->status=0;				// May be wrong if quick_select

  // If table has a range, move it to select
  if (select && !select->quick && tab->ref.key >= 0)
  {
    if (tab->quick)
    {
      select->quick=tab->quick;
      tab->quick=0;
unknown's avatar
unknown committed
11065 11066 11067 11068 11069
      /* 
        We can only use 'Only index' if quick key is same as ref_key
        and in index_merge 'Only index' cannot be used
      */
      if (table->key_read && ((uint) tab->ref.key != select->quick->index))
unknown's avatar
unknown committed
11070 11071 11072 11073 11074 11075 11076 11077 11078 11079
      {
	table->key_read=0;
	table->file->extra(HA_EXTRA_NO_KEYREAD);
      }
    }
    else
    {
      /*
	We have a ref on a const;  Change this to a range that filesort
	can use.
11080 11081
	For impossible ranges (like when doing a lookup on NULL on a NOT NULL
	field, quick will contain an empty record set.
unknown's avatar
unknown committed
11082
      */
unknown's avatar
af  
unknown committed
11083 11084
      if (!(select->quick= (tab->type == JT_FT ?
			    new FT_SELECT(thd, table, tab->ref.key) :
unknown's avatar
unknown committed
11085 11086
			    get_quick_select_for_ref(thd, table, &tab->ref, 
                                                     tab->found_records))))
unknown's avatar
unknown committed
11087 11088 11089
	goto err;
    }
  }
11090
  if (table->s->tmp_table)
11091
    table->file->info(HA_STATUS_VARIABLE);	// Get record count
unknown's avatar
unknown committed
11092 11093
  table->sort.found_records=filesort(thd, table,sortorder, length,
                                     select, filesort_limit, &examined_rows);
unknown's avatar
af  
unknown committed
11094 11095 11096 11097 11098 11099
  tab->records= table->sort.found_records;	// For SQL_CALC_ROWS
  if (select)
  {
    select->cleanup();				// filesort did select
    tab->select= 0;
  }
unknown's avatar
unknown committed
11100
  tab->select_cond=0;
11101 11102
  tab->last_inner= 0;
  tab->first_unmatched= 0;
unknown's avatar
unknown committed
11103 11104
  tab->type=JT_ALL;				// Read with normal read_record
  tab->read_first_record= join_init_read_record;
11105
  tab->join->examined_rows+=examined_rows;
unknown's avatar
unknown committed
11106 11107 11108 11109 11110
  if (table->key_read)				// Restore if we used indexes
  {
    table->key_read=0;
    table->file->extra(HA_EXTRA_NO_KEYREAD);
  }
unknown's avatar
unknown committed
11111
  DBUG_RETURN(table->sort.found_records == HA_POS_ERROR);
unknown's avatar
unknown committed
11112 11113 11114 11115
err:
  DBUG_RETURN(-1);
}

11116
/*
11117
  Add the HAVING criteria to table->select
11118 11119
*/

unknown's avatar
unknown committed
11120
#ifdef NOT_YET
11121 11122 11123 11124 11125 11126
static bool fix_having(JOIN *join, Item **having)
{
  (*having)->update_used_tables();	// Some tables may have been const
  JOIN_TAB *table=&join->join_tab[join->const_tables];
  table_map used_tables= join->const_table_map | table->table->map;

unknown's avatar
unknown committed
11127
  DBUG_EXECUTE("where",print_where(*having,"having"););
11128 11129 11130 11131 11132 11133 11134 11135 11136
  Item* sort_table_cond=make_cond_for_table(*having,used_tables,used_tables);
  if (sort_table_cond)
  {
    if (!table->select)
      if (!(table->select=new SQL_SELECT))
	return 1;
    if (!table->select->cond)
      table->select->cond=sort_table_cond;
    else					// This should never happen
unknown's avatar
af  
unknown committed
11137 11138 11139 11140
      if (!(table->select->cond= new Item_cond_and(table->select->cond,
						   sort_table_cond)) ||
	  table->select->cond->fix_fields(join->thd, join->tables_list,
					  &table->select->cond))
11141 11142
	return 1;
    table->select_cond=table->select->cond;
11143
    table->select_cond->top_level_item();
11144 11145 11146 11147 11148 11149 11150
    DBUG_EXECUTE("where",print_where(table->select_cond,
				     "select and having"););
    *having=make_cond_for_table(*having,~ (table_map) 0,~used_tables);
    DBUG_EXECUTE("where",print_where(*having,"having after make_cond"););
  }
  return 0;
}
unknown's avatar
unknown committed
11151
#endif
11152 11153


unknown's avatar
unknown committed
11154
/*****************************************************************************
11155 11156 11157 11158 11159
  Remove duplicates from tmp table
  This should be recoded to add a unique index to the table and remove
  duplicates
  Table is a locked single thread table
  fields is the number of fields to check (from the end)
unknown's avatar
unknown committed
11160 11161 11162 11163 11164 11165
*****************************************************************************/

static bool compare_record(TABLE *table, Field **ptr)
{
  for (; *ptr ; ptr++)
  {
11166
    if ((*ptr)->cmp_offset(table->s->rec_buff_length))
unknown's avatar
unknown committed
11167 11168 11169 11170 11171 11172 11173 11174 11175 11176 11177 11178 11179 11180 11181 11182 11183 11184 11185 11186 11187 11188 11189 11190 11191 11192 11193
      return 1;
  }
  return 0;
}

static bool copy_blobs(Field **ptr)
{
  for (; *ptr ; ptr++)
  {
    if ((*ptr)->flags & BLOB_FLAG)
      if (((Field_blob *) (*ptr))->copy())
	return 1;				// Error
  }
  return 0;
}

static void free_blobs(Field **ptr)
{
  for (; *ptr ; ptr++)
  {
    if ((*ptr)->flags & BLOB_FLAG)
      ((Field_blob *) (*ptr))->free();
  }
}


static int
11194
remove_duplicates(JOIN *join, TABLE *entry,List<Item> &fields, Item *having)
unknown's avatar
unknown committed
11195 11196 11197 11198
{
  int error;
  ulong reclength,offset;
  uint field_count;
11199
  THD *thd= join->thd;
unknown's avatar
unknown committed
11200 11201 11202 11203 11204 11205 11206 11207 11208
  DBUG_ENTER("remove_duplicates");

  entry->reginfo.lock_type=TL_WRITE;

  /* Calculate how many saved fields there is in list */
  field_count=0;
  List_iterator<Item> it(fields);
  Item *item;
  while ((item=it++))
unknown's avatar
unknown committed
11209
  {
11210
    if (item->get_tmp_table_field() && ! item->const_item())
unknown's avatar
unknown committed
11211
      field_count++;
unknown's avatar
unknown committed
11212
  }
unknown's avatar
unknown committed
11213

11214 11215
  if (!field_count && !(join->select_options & OPTION_FOUND_ROWS)) 
  {                    // only const items with no OPTION_FOUND_ROWS
11216
    join->unit->select_limit_cnt= 1;		// Only send first row
unknown's avatar
unknown committed
11217 11218
    DBUG_RETURN(0);
  }
11219
  Field **first_field=entry->field+entry->s->fields - field_count;
11220
  offset= field_count ? 
unknown's avatar
unknown committed
11221
          entry->field[entry->s->fields - field_count]->offset() : 0;
11222
  reclength=entry->s->reclength-offset;
unknown's avatar
unknown committed
11223 11224 11225

  free_io_cache(entry);				// Safety
  entry->file->info(HA_STATUS_VARIABLE);
11226 11227
  if (entry->s->db_type == DB_TYPE_HEAP ||
      (!entry->s->blob_fields &&
unknown's avatar
unknown committed
11228
       ((ALIGN_SIZE(reclength) + HASH_OVERHEAD) * entry->file->records <
11229
	thd->variables.sortbuff_size)))
unknown's avatar
unknown committed
11230 11231
    error=remove_dup_with_hash_index(join->thd, entry,
				     field_count, first_field,
11232
				     reclength, having);
unknown's avatar
unknown committed
11233
  else
11234 11235
    error=remove_dup_with_compare(join->thd, entry, first_field, offset,
				  having);
unknown's avatar
unknown committed
11236 11237 11238 11239 11240 11241 11242

  free_blobs(first_field);
  DBUG_RETURN(error);
}


static int remove_dup_with_compare(THD *thd, TABLE *table, Field **first_field,
11243
				   ulong offset, Item *having)
unknown's avatar
unknown committed
11244 11245 11246
{
  handler *file=table->file;
  char *org_record,*new_record;
unknown's avatar
unknown committed
11247
  byte *record;
unknown's avatar
unknown committed
11248
  int error;
11249
  ulong reclength= table->s->reclength-offset;
unknown's avatar
unknown committed
11250 11251
  DBUG_ENTER("remove_dup_with_compare");

11252
  org_record=(char*) (record=table->record[0])+offset;
unknown's avatar
unknown committed
11253 11254
  new_record=(char*) table->record[1]+offset;

11255
  file->ha_rnd_init(1);
11256
  error=file->rnd_next(record);
unknown's avatar
unknown committed
11257 11258 11259 11260
  for (;;)
  {
    if (thd->killed)
    {
unknown's avatar
SCRUM  
unknown committed
11261
      thd->send_kill_message();
unknown's avatar
unknown committed
11262 11263 11264 11265 11266 11267 11268 11269 11270 11271 11272
      error=0;
      goto err;
    }
    if (error)
    {
      if (error == HA_ERR_RECORD_DELETED)
	continue;
      if (error == HA_ERR_END_OF_FILE)
	break;
      goto err;
    }
11273 11274 11275 11276
    if (having && !having->val_int())
    {
      if ((error=file->delete_row(record)))
	goto err;
11277
      error=file->rnd_next(record);
11278 11279
      continue;
    }
unknown's avatar
unknown committed
11280 11281
    if (copy_blobs(first_field))
    {
unknown's avatar
unknown committed
11282
      my_message(ER_OUTOFMEMORY, ER(ER_OUTOFMEMORY), MYF(0));
unknown's avatar
unknown committed
11283 11284 11285 11286 11287 11288 11289 11290 11291
      error=0;
      goto err;
    }
    memcpy(new_record,org_record,reclength);

    /* Read through rest of file and mark duplicated rows deleted */
    bool found=0;
    for (;;)
    {
11292
      if ((error=file->rnd_next(record)))
unknown's avatar
unknown committed
11293 11294 11295 11296 11297 11298 11299 11300 11301
      {
	if (error == HA_ERR_RECORD_DELETED)
	  continue;
	if (error == HA_ERR_END_OF_FILE)
	  break;
	goto err;
      }
      if (compare_record(table, first_field) == 0)
      {
11302
	if ((error=file->delete_row(record)))
unknown's avatar
unknown committed
11303 11304 11305 11306 11307
	  goto err;
      }
      else if (!found)
      {
	found=1;
11308
	file->position(record);	// Remember position
unknown's avatar
unknown committed
11309 11310 11311 11312 11313
      }
    }
    if (!found)
      break;					// End of file
    /* Restart search on next row */
11314
    error=file->restart_rnd_next(record,file->ref);
unknown's avatar
unknown committed
11315 11316 11317 11318 11319 11320 11321 11322 11323 11324 11325 11326 11327 11328 11329 11330 11331 11332 11333 11334
  }

  file->extra(HA_EXTRA_NO_CACHE);
  DBUG_RETURN(0);
err:
  file->extra(HA_EXTRA_NO_CACHE);
  if (error)
    file->print_error(error,MYF(0));
  DBUG_RETURN(1);
}


/*
  Generate a hash index for each row to quickly find duplicate rows
  Note that this will not work on tables with blobs!
*/

static int remove_dup_with_hash_index(THD *thd, TABLE *table,
				      uint field_count,
				      Field **first_field,
11335 11336
				      ulong key_length,
				      Item *having)
unknown's avatar
unknown committed
11337 11338 11339
{
  byte *key_buffer, *key_pos, *record=table->record[0];
  int error;
11340 11341
  handler *file= table->file;
  ulong extra_length= ALIGN_SIZE(key_length)-key_length;
unknown's avatar
unknown committed
11342 11343 11344 11345 11346 11347 11348 11349 11350 11351 11352 11353
  uint *field_lengths,*field_length;
  HASH hash;
  DBUG_ENTER("remove_dup_with_hash_index");

  if (!my_multi_malloc(MYF(MY_WME),
		       &key_buffer,
		       (uint) ((key_length + extra_length) *
			       (long) file->records),
		       &field_lengths,
		       (uint) (field_count*sizeof(*field_lengths)),
		       NullS))
    DBUG_RETURN(1);
unknown's avatar
unknown committed
11354

11355 11356 11357 11358 11359 11360 11361 11362 11363 11364 11365 11366 11367 11368 11369 11370
  {
    Field **ptr;
    ulong total_length= 0;
    for (ptr= first_field, field_length=field_lengths ; *ptr ; ptr++)
    {
      uint length= (*ptr)->pack_length();
      (*field_length++)= length;
      total_length+= length;
    }
    DBUG_PRINT("info",("field_count: %u  key_length: %lu  total_length: %lu",
                       field_count, key_length, total_length));
    DBUG_ASSERT(total_length <= key_length);
    key_length= total_length;
    extra_length= ALIGN_SIZE(key_length)-key_length;
  }

unknown's avatar
unknown committed
11371
  if (hash_init(&hash, &my_charset_bin, (uint) file->records, 0, 
11372
		key_length, (hash_get_key) 0, 0, 0))
unknown's avatar
unknown committed
11373 11374 11375 11376 11377
  {
    my_free((char*) key_buffer,MYF(0));
    DBUG_RETURN(1);
  }

11378
  file->ha_rnd_init(1);
unknown's avatar
unknown committed
11379 11380 11381
  key_pos=key_buffer;
  for (;;)
  {
11382
    byte *org_key_pos;
unknown's avatar
unknown committed
11383 11384
    if (thd->killed)
    {
unknown's avatar
SCRUM  
unknown committed
11385
      thd->send_kill_message();
unknown's avatar
unknown committed
11386 11387 11388 11389 11390 11391 11392 11393 11394 11395 11396
      error=0;
      goto err;
    }
    if ((error=file->rnd_next(record)))
    {
      if (error == HA_ERR_RECORD_DELETED)
	continue;
      if (error == HA_ERR_END_OF_FILE)
	break;
      goto err;
    }
11397 11398 11399 11400 11401
    if (having && !having->val_int())
    {
      if ((error=file->delete_row(record)))
	goto err;
      continue;
11402
    }
unknown's avatar
unknown committed
11403 11404

    /* copy fields to key buffer */
11405
    org_key_pos= key_pos;
unknown's avatar
unknown committed
11406 11407 11408 11409 11410 11411 11412
    field_length=field_lengths;
    for (Field **ptr= first_field ; *ptr ; ptr++)
    {
      (*ptr)->sort_string((char*) key_pos,*field_length);
      key_pos+= *field_length++;
    }
    /* Check if it exists before */
11413
    if (hash_search(&hash, org_key_pos, key_length))
unknown's avatar
unknown committed
11414 11415 11416 11417 11418
    {
      /* Duplicated found ; Remove the row */
      if ((error=file->delete_row(record)))
	goto err;
    }
11419
    else
11420
      (void) my_hash_insert(&hash, org_key_pos);
unknown's avatar
unknown committed
11421 11422 11423 11424 11425
    key_pos+=extra_length;
  }
  my_free((char*) key_buffer,MYF(0));
  hash_free(&hash);
  file->extra(HA_EXTRA_NO_CACHE);
unknown's avatar
unknown committed
11426
  (void) file->ha_rnd_end();
unknown's avatar
unknown committed
11427 11428 11429 11430 11431 11432
  DBUG_RETURN(0);

err:
  my_free((char*) key_buffer,MYF(0));
  hash_free(&hash);
  file->extra(HA_EXTRA_NO_CACHE);
unknown's avatar
unknown committed
11433
  (void) file->ha_rnd_end();
unknown's avatar
unknown committed
11434 11435 11436 11437 11438 11439
  if (error)
    file->print_error(error,MYF(0));
  DBUG_RETURN(1);
}


unknown's avatar
unknown committed
11440
SORT_FIELD *make_unireg_sortorder(ORDER *order, uint *length)
unknown's avatar
unknown committed
11441 11442 11443 11444 11445 11446 11447 11448 11449 11450 11451 11452 11453 11454 11455 11456 11457 11458 11459
{
  uint count;
  SORT_FIELD *sort,*pos;
  DBUG_ENTER("make_unireg_sortorder");

  count=0;
  for (ORDER *tmp = order; tmp; tmp=tmp->next)
    count++;
  pos=sort=(SORT_FIELD*) sql_alloc(sizeof(SORT_FIELD)*(count+1));
  if (!pos)
    return 0;

  for (;order;order=order->next,pos++)
  {
    pos->field=0; pos->item=0;
    if (order->item[0]->type() == Item::FIELD_ITEM)
      pos->field= ((Item_field*) (*order->item))->field;
    else if (order->item[0]->type() == Item::SUM_FUNC_ITEM &&
	     !order->item[0]->const_item())
11460
      pos->field= ((Item_sum*) order->item[0])->get_tmp_table_field();
unknown's avatar
unknown committed
11461 11462 11463 11464 11465 11466 11467 11468 11469 11470 11471 11472 11473 11474
    else if (order->item[0]->type() == Item::COPY_STR_ITEM)
    {						// Blob patch
      pos->item= ((Item_copy_string*) (*order->item))->item;
    }
    else
      pos->item= *order->item;
    pos->reverse=! order->asc;
  }
  *length=count;
  DBUG_RETURN(sort);
}


/*****************************************************************************
11475 11476 11477 11478
  Fill join cache with packed records
  Records are stored in tab->cache.buffer and last record in
  last record is stored with pointers to blobs to support very big
  records
unknown's avatar
unknown committed
11479 11480 11481 11482 11483 11484 11485 11486 11487
******************************************************************************/

static int
join_init_cache(THD *thd,JOIN_TAB *tables,uint table_count)
{
  reg1 uint i;
  uint length,blobs,size;
  CACHE_FIELD *copy,**blob_ptr;
  JOIN_CACHE  *cache;
11488
  JOIN_TAB *join_tab;
unknown's avatar
unknown committed
11489 11490 11491 11492 11493
  DBUG_ENTER("join_init_cache");

  cache= &tables[table_count].cache;
  cache->fields=blobs=0;

11494 11495
  join_tab=tables;
  for (i=0 ; i < table_count ; i++,join_tab++)
unknown's avatar
unknown committed
11496
  {
11497 11498 11499 11500
    if (!join_tab->used_fieldlength)		/* Not calced yet */
      calc_used_field_length(thd, join_tab);
    cache->fields+=join_tab->used_fields;
    blobs+=join_tab->used_blobs;
unknown's avatar
unknown committed
11501 11502 11503
  }
  if (!(cache->field=(CACHE_FIELD*)
	sql_alloc(sizeof(CACHE_FIELD)*(cache->fields+table_count*2)+(blobs+1)*
unknown's avatar
unknown committed
11504

unknown's avatar
unknown committed
11505 11506 11507 11508 11509 11510 11511 11512 11513 11514 11515 11516 11517 11518 11519 11520 11521 11522 11523 11524 11525 11526 11527 11528 11529 11530 11531 11532 11533 11534 11535 11536 11537
		  sizeof(CACHE_FIELD*))))
  {
    my_free((gptr) cache->buff,MYF(0));		/* purecov: inspected */
    cache->buff=0;				/* purecov: inspected */
    DBUG_RETURN(1);				/* purecov: inspected */
  }
  copy=cache->field;
  blob_ptr=cache->blob_ptr=(CACHE_FIELD**)
    (cache->field+cache->fields+table_count*2);

  length=0;
  for (i=0 ; i < table_count ; i++)
  {
    uint null_fields=0,used_fields;

    Field **f_ptr,*field;
    for (f_ptr=tables[i].table->field,used_fields=tables[i].used_fields ;
	 used_fields ;
	 f_ptr++)
    {
      field= *f_ptr;
      if (field->query_id == thd->query_id)
      {
	used_fields--;
	length+=field->fill_cache_field(copy);
	if (copy->blob_field)
	  (*blob_ptr++)=copy;
	if (field->maybe_null())
	  null_fields++;
	copy++;
      }
    }
    /* Copy null bits from table */
11538
    if (null_fields && tables[i].table->s->null_fields)
unknown's avatar
unknown committed
11539 11540
    {						/* must copy null bits */
      copy->str=(char*) tables[i].table->null_flags;
11541
      copy->length= tables[i].table->s->null_bytes;
unknown's avatar
unknown committed
11542 11543 11544 11545 11546 11547 11548 11549 11550 11551 11552 11553 11554 11555 11556 11557 11558 11559 11560 11561 11562 11563
      copy->strip=0;
      copy->blob_field=0;
      length+=copy->length;
      copy++;
      cache->fields++;
    }
    /* If outer join table, copy null_row flag */
    if (tables[i].table->maybe_null)
    {
      copy->str= (char*) &tables[i].table->null_row;
      copy->length=sizeof(tables[i].table->null_row);
      copy->strip=0;
      copy->blob_field=0;
      length+=copy->length;
      copy++;
      cache->fields++;
    }
  }

  cache->length=length+blobs*sizeof(char*);
  cache->blobs=blobs;
  *blob_ptr=0;					/* End sequentel */
11564
  size=max(thd->variables.join_buff_size, cache->length);
unknown's avatar
unknown committed
11565 11566 11567
  if (!(cache->buff=(uchar*) my_malloc(size,MYF(0))))
    DBUG_RETURN(1);				/* Don't use cache */ /* purecov: inspected */
  cache->end=cache->buff+size;
11568
  reset_cache_write(cache);
unknown's avatar
unknown committed
11569 11570 11571 11572 11573 11574 11575 11576 11577 11578 11579 11580 11581 11582 11583 11584 11585 11586 11587 11588 11589 11590 11591 11592 11593 11594 11595 11596 11597 11598 11599 11600 11601 11602 11603 11604
  DBUG_RETURN(0);
}


static ulong
used_blob_length(CACHE_FIELD **ptr)
{
  uint length,blob_length;
  for (length=0 ; *ptr ; ptr++)
  {
    (*ptr)->blob_length=blob_length=(*ptr)->blob_field->get_length();
    length+=blob_length;
    (*ptr)->blob_field->get_ptr(&(*ptr)->str);
  }
  return length;
}


static bool
store_record_in_cache(JOIN_CACHE *cache)
{
  ulong length;
  uchar *pos;
  CACHE_FIELD *copy,*end_field;
  bool last_record;

  pos=cache->pos;
  end_field=cache->field+cache->fields;

  length=cache->length;
  if (cache->blobs)
    length+=used_blob_length(cache->blob_ptr);
  if ((last_record=(length+cache->length > (uint) (cache->end - pos))))
    cache->ptr_record=cache->records;

  /*
11605
    There is room in cache. Put record there
unknown's avatar
unknown committed
11606 11607 11608 11609 11610 11611 11612 11613
  */
  cache->records++;
  for (copy=cache->field ; copy < end_field; copy++)
  {
    if (copy->blob_field)
    {
      if (last_record)
      {
unknown's avatar
unknown committed
11614 11615
	copy->blob_field->get_image((char*) pos,copy->length+sizeof(char*), 
				    copy->blob_field->charset());
unknown's avatar
unknown committed
11616 11617 11618 11619
	pos+=copy->length+sizeof(char*);
      }
      else
      {
unknown's avatar
unknown committed
11620 11621
	copy->blob_field->get_image((char*) pos,copy->length, // blob length
				    copy->blob_field->charset());
unknown's avatar
unknown committed
11622 11623 11624 11625 11626 11627 11628 11629 11630 11631 11632 11633 11634 11635 11636 11637 11638 11639 11640 11641 11642 11643 11644 11645 11646 11647 11648 11649 11650 11651
	memcpy(pos+copy->length,copy->str,copy->blob_length);  // Blob data
	pos+=copy->length+copy->blob_length;
      }
    }
    else
    {
      if (copy->strip)
      {
	char *str,*end;
	for (str=copy->str,end= str+copy->length;
	     end > str && end[-1] == ' ' ;
	     end--) ;
	length=(uint) (end-str);
	memcpy(pos+1,str,length);
	*pos=(uchar) length;
	pos+=length+1;
      }
      else
      {
	memcpy(pos,copy->str,copy->length);
	pos+=copy->length;
      }
    }
  }
  cache->pos=pos;
  return last_record || (uint) (cache->end -pos) < cache->length;
}


static void
11652
reset_cache_read(JOIN_CACHE *cache)
unknown's avatar
unknown committed
11653 11654 11655 11656 11657 11658
{
  cache->record_nr=0;
  cache->pos=cache->buff;
}


11659 11660 11661 11662 11663
static void reset_cache_write(JOIN_CACHE *cache)
{
  reset_cache_read(cache);
  cache->records= 0;
  cache->ptr_record= (uint) ~0;
unknown's avatar
unknown committed
11664 11665 11666 11667 11668 11669 11670 11671 11672 11673 11674 11675 11676 11677 11678 11679 11680 11681 11682 11683 11684 11685
}


static void
read_cached_record(JOIN_TAB *tab)
{
  uchar *pos;
  uint length;
  bool last_record;
  CACHE_FIELD *copy,*end_field;

  last_record=tab->cache.record_nr++ == tab->cache.ptr_record;
  pos=tab->cache.pos;

  for (copy=tab->cache.field,end_field=copy+tab->cache.fields ;
       copy < end_field;
       copy++)
  {
    if (copy->blob_field)
    {
      if (last_record)
      {
unknown's avatar
unknown committed
11686 11687
	copy->blob_field->set_image((char*) pos,copy->length+sizeof(char*),
				    copy->blob_field->charset());
unknown's avatar
unknown committed
11688 11689 11690 11691 11692 11693 11694 11695 11696 11697 11698 11699 11700 11701 11702 11703 11704 11705 11706 11707 11708 11709 11710 11711 11712 11713 11714 11715 11716 11717 11718 11719 11720 11721 11722 11723
	pos+=copy->length+sizeof(char*);
      }
      else
      {
	copy->blob_field->set_ptr((char*) pos,(char*) pos+copy->length);
	pos+=copy->length+copy->blob_field->get_length();
      }
    }
    else
    {
      if (copy->strip)
      {
	memcpy(copy->str,pos+1,length=(uint) *pos);
	memset(copy->str+length,' ',copy->length-length);
	pos+=1+length;
      }
      else
      {
	memcpy(copy->str,pos,copy->length);
	pos+=copy->length;
      }
    }
  }
  tab->cache.pos=pos;
  return;
}


static bool
cmp_buffer_with_ref(JOIN_TAB *tab)
{
  bool diff;
  if (!(diff=tab->ref.key_err))
  {
    memcpy(tab->ref.key_buff2, tab->ref.key_buff, tab->ref.key_length);
  }
unknown's avatar
unknown committed
11724 11725
  if ((tab->ref.key_err= cp_buffer_from_ref(tab->join->thd, &tab->ref)) || 
      diff)
unknown's avatar
unknown committed
11726 11727 11728 11729 11730 11731 11732
    return 1;
  return memcmp(tab->ref.key_buff2, tab->ref.key_buff, tab->ref.key_length)
    != 0;
}


bool
unknown's avatar
unknown committed
11733
cp_buffer_from_ref(THD *thd, TABLE_REF *ref)
unknown's avatar
unknown committed
11734
{
unknown's avatar
unknown committed
11735 11736
  enum enum_check_fields save_count_cuted_fields= thd->count_cuted_fields;
  thd->count_cuted_fields= CHECK_FIELD_IGNORE;
unknown's avatar
unknown committed
11737
  for (store_key **copy=ref->key_copy ; *copy ; copy++)
unknown's avatar
unknown committed
11738
  {
unknown's avatar
unknown committed
11739
    if ((*copy)->copy())
unknown's avatar
unknown committed
11740 11741
    {
      thd->count_cuted_fields= save_count_cuted_fields;
unknown's avatar
unknown committed
11742
      return 1;					// Something went wrong
unknown's avatar
unknown committed
11743
    }
unknown's avatar
unknown committed
11744
  }
unknown's avatar
unknown committed
11745
  thd->count_cuted_fields= save_count_cuted_fields;
unknown's avatar
unknown committed
11746 11747 11748 11749 11750
  return 0;
}


/*****************************************************************************
11751
  Group and order functions
unknown's avatar
unknown committed
11752 11753 11754
*****************************************************************************/

/*
11755 11756 11757 11758 11759 11760 11761 11762 11763 11764 11765 11766 11767 11768 11769 11770 11771 11772 11773 11774 11775 11776 11777 11778 11779 11780
  Resolve an ORDER BY or GROUP BY column reference.

  SYNOPSIS
    find_order_in_list()
    thd		      [in]     Pointer to current thread structure
    ref_pointer_array [in/out] All select, group and order by fields
    tables            [in]     List of tables to search in (usually FROM clause)
    order             [in]     Column reference to be resolved
    fields            [in]     List of fields to search in (usually SELECT list)
    all_fields        [in/out] All select, group and order by fields
    is_group_field    [in]     True if order is a GROUP field, false if
                               ORDER by field

  DESCRIPTION
    Given a column reference (represented by 'order') from a GROUP BY or ORDER
    BY clause, find the actual column it represents. If the column being
    resolved is from the GROUP BY clause, the procedure searches the SELECT
    list 'fields' and the columns in the FROM list 'tables'. If 'order' is from
    the ORDER BY clause, only the SELECT list is being searched.

    If 'order' is resolved to an Item, then order->item is set to the found
    Item. If there is no item for the found column (that is, it was resolved
    into a table field), order->item is 'fixed' and is added to all_fields and
    ref_pointer_array.

  RETURN
unknown's avatar
unknown committed
11781
    0 if OK
11782
    1 if error occurred
unknown's avatar
unknown committed
11783 11784 11785
*/

static int
11786 11787 11788
find_order_in_list(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables,
                   ORDER *order, List<Item> &fields, List<Item> &all_fields,
                   bool is_group_field)
unknown's avatar
unknown committed
11789
{
11790
  Item *order_item= *order->item; /* The item from the GROUP/ORDER caluse. */
11791 11792 11793 11794 11795
  Item::Type order_item_type;
  Item **select_item; /* The corresponding item from the SELECT clause. */
  Field *from_field;  /* The corresponding field from the FROM clause. */

  if (order_item->type() == Item::INT_ITEM)
unknown's avatar
unknown committed
11796
  {						/* Order by position */
11797
    uint count= (uint) order_item->val_int();
unknown's avatar
unknown committed
11798
    if (!count || count > fields.elements)
unknown's avatar
unknown committed
11799
    {
11800 11801
      my_error(ER_BAD_FIELD_ERROR, MYF(0),
               order_item->full_name(), thd->where);
unknown's avatar
unknown committed
11802 11803
      return 1;
    }
11804
    order->item= ref_pointer_array + count - 1;
11805
    order->in_field_list= 1;
11806 11807
    order->counter= count;
    order->counter_used= 1;
unknown's avatar
unknown committed
11808 11809
    return 0;
  }
11810
  /* Lookup the current GROUP/ORDER field in the SELECT clause. */
11811
  uint counter;
11812
  bool unaliased;
11813
  select_item= find_item_in_list(order_item, fields, &counter,
11814
                                 REPORT_EXCEPT_NOT_FOUND, &unaliased);
11815 11816
  if (!select_item)
    return 1; /* Some error occured. */
11817 11818


11819 11820
  /* Check whether the resolved field is not ambiguos. */
  if (select_item != not_found_item)
unknown's avatar
unknown committed
11821
  {
11822
    Item *view_ref= NULL;
11823 11824 11825 11826 11827
    /*
      If we have found field not by its alias in select list but by its
      original field name, we should additionaly check if we have conflict
      for this name (in case if we would perform lookup in all tables).
    */
11828 11829
    if (unaliased && !order_item->fixed && order_item->fix_fields(thd, tables,
                                                                  order->item))
11830 11831
      return 1;

11832 11833 11834
    /* Lookup the current GROUP field in the FROM clause. */
    order_item_type= order_item->type();
    if (is_group_field &&
11835 11836
        order_item_type == Item::FIELD_ITEM ||
        order_item_type == Item::REF_ITEM)
11837 11838
    {
      from_field= find_field_in_tables(thd, (Item_ident*) order_item, tables,
11839
                                       &view_ref, IGNORE_ERRORS, TRUE);
11840 11841 11842 11843 11844 11845 11846
      if(!from_field)
       from_field= (Field*) not_found_field;
    }
    else
      from_field= (Field*) not_found_field;

    if (from_field == not_found_field ||
11847 11848 11849 11850 11851 11852 11853 11854 11855
        from_field &&
        (from_field != view_ref_found ?
         /* it is field of base table => check that fields are same */
         ((*select_item)->type() == Item::FIELD_ITEM &&
          ((Item_field*) (*select_item))->field->eq(from_field)) :
         /*
           in is field of view table => check that references on translation
           table are same
         */
unknown's avatar
unknown committed
11856 11857
         ((*select_item)->type() == Item::REF_ITEM &&
          view_ref->type() == Item::REF_ITEM &&
11858 11859
          ((Item_ref *) (*select_item))->ref ==
          ((Item_ref *) view_ref)->ref)))
11860 11861 11862 11863 11864 11865 11866 11867 11868 11869 11870 11871
      /*
        If there is no such field in the FROM clause, or it is the same field as
        the one found in the SELECT clause, then use the Item created for the
        SELECT field. As a result if there was a derived field that 'shadowed'
        a table field with the same name, the table field will be chosen over
        the derived field.
      */
    {
      order->item= ref_pointer_array + counter;
      order->in_field_list=1;
      return 0;
    }
unknown's avatar
unknown committed
11872
  }
11873

unknown's avatar
unknown committed
11874
  order->in_field_list=0;
unknown's avatar
af  
unknown committed
11875
  /*
11876
    We check order_item->fixed because Item_func_group_concat can put
unknown's avatar
af  
unknown committed
11877 11878 11879 11880
    arguments for which fix_fields already was called.

    'it' reassigned in if condition because fix_field can change it.
  */
11881 11882 11883
  if (!order_item->fixed &&
      (order_item->fix_fields(thd, tables, order->item) ||
       (order_item= *order->item)->check_cols(1) ||
unknown's avatar
af  
unknown committed
11884
       thd->is_fatal_error))
11885
    return 1;					// Wrong field 
11886
  uint el= all_fields.elements;
unknown's avatar
unknown committed
11887 11888
  all_fields.push_front(order_item);		        // Add new field to field list
  ref_pointer_array[el]= order_item;
11889
  order->item= ref_pointer_array + el;
unknown's avatar
unknown committed
11890 11891 11892
  return 0;
}

11893

unknown's avatar
unknown committed
11894
/*
11895 11896
  Change order to point at item in select list. If item isn't a number
  and doesn't exits in the select list, add it the the field list.
unknown's avatar
unknown committed
11897 11898
*/

11899 11900
int setup_order(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables,
		List<Item> &fields, List<Item> &all_fields, ORDER *order)
unknown's avatar
unknown committed
11901 11902 11903 11904
{
  thd->where="order clause";
  for (; order; order=order->next)
  {
11905
    if (find_order_in_list(thd, ref_pointer_array, tables, order, fields,
11906
			   all_fields, FALSE))
unknown's avatar
unknown committed
11907 11908 11909 11910 11911 11912
      return 1;
  }
  return 0;
}


unknown's avatar
af  
unknown committed
11913 11914 11915 11916 11917 11918 11919
/*
  Intitialize the GROUP BY list.

  SYNOPSIS
   setup_group()
   thd			Thread handler
   ref_pointer_array	We store references to all fields that was not in
unknown's avatar
unknown committed
11920
			'fields' here.
unknown's avatar
af  
unknown committed
11921 11922 11923 11924 11925 11926 11927 11928 11929 11930 11931 11932 11933 11934 11935
   fields		All fields in the select part. Any item in 'order'
			that is part of these list is replaced by a pointer
			to this fields.
   all_fields		Total list of all unique fields used by the select.
			All items in 'order' that was not part of fields will
			be added first to this list.
  order			The fields we should do GROUP BY on.
  hidden_group_fields	Pointer to flag that is set to 1 if we added any fields
			to all_fields.

  RETURN
   0  ok
   1  error (probably out of memory)
*/

unknown's avatar
unknown committed
11936
int
11937 11938 11939
setup_group(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables,
	    List<Item> &fields, List<Item> &all_fields, ORDER *order,
	    bool *hidden_group_fields)
unknown's avatar
unknown committed
11940 11941 11942 11943 11944
{
  *hidden_group_fields=0;
  if (!order)
    return 0;				/* Everything is ok */

11945
  if (thd->variables.sql_mode & MODE_ONLY_FULL_GROUP_BY)
unknown's avatar
unknown committed
11946 11947 11948 11949 11950 11951 11952 11953 11954
  {
    Item *item;
    List_iterator<Item> li(fields);
    while ((item=li++))
      item->marker=0;			/* Marker that field is not used */
  }
  uint org_fields=all_fields.elements;

  thd->where="group statement";
11955
  for (; order; order=order->next)
unknown's avatar
unknown committed
11956
  {
11957
    if (find_order_in_list(thd, ref_pointer_array, tables, order, fields,
11958
			   all_fields, TRUE))
unknown's avatar
unknown committed
11959 11960 11961 11962
      return 1;
    (*order->item)->marker=1;		/* Mark found */
    if ((*order->item)->with_sum_func)
    {
11963
      my_error(ER_WRONG_GROUP_FIELD, MYF(0), (*order->item)->full_name());
unknown's avatar
unknown committed
11964 11965 11966
      return 1;
    }
  }
11967
  if (thd->variables.sql_mode & MODE_ONLY_FULL_GROUP_BY)
unknown's avatar
unknown committed
11968 11969 11970 11971 11972 11973 11974
  {
    /* Don't allow one to use fields that is not used in GROUP BY */
    Item *item;
    List_iterator<Item> li(fields);

    while ((item=li++))
    {
11975 11976
      if (item->type() != Item::SUM_FUNC_ITEM && !item->marker &&
	  !item->const_item())
unknown's avatar
unknown committed
11977
      {
11978
	my_error(ER_WRONG_FIELD_WITH_GROUP, MYF(0), item->full_name());
unknown's avatar
unknown committed
11979 11980 11981 11982 11983 11984 11985 11986 11987 11988
	return 1;
      }
    }
  }
  if (org_fields != all_fields.elements)
    *hidden_group_fields=1;			// group fields is not used
  return 0;
}

/*
11989
  Add fields with aren't used at start of field list. Return FALSE if ok
unknown's avatar
unknown committed
11990 11991 11992 11993 11994 11995 11996 11997 11998 11999
*/

static bool
setup_new_fields(THD *thd,TABLE_LIST *tables,List<Item> &fields,
		 List<Item> &all_fields, ORDER *new_field)
{
  Item	  **item;
  DBUG_ENTER("setup_new_fields");

  thd->set_query_id=1;				// Not really needed, but...
12000
  uint counter;
12001
  bool not_used;
unknown's avatar
unknown committed
12002
  for (; new_field ; new_field= new_field->next)
unknown's avatar
unknown committed
12003
  {
12004
    if ((item= find_item_in_list(*new_field->item, fields, &counter,
12005
				 IGNORE_ERRORS, &not_used)))
unknown's avatar
unknown committed
12006 12007 12008 12009
      new_field->item=item;			/* Change to shared Item */
    else
    {
      thd->where="procedure list";
unknown's avatar
unknown committed
12010
      if ((*new_field->item)->fix_fields(thd, tables, new_field->item))
unknown's avatar
unknown committed
12011 12012 12013 12014 12015 12016 12017 12018 12019
	DBUG_RETURN(1); /* purecov: inspected */
      all_fields.push_front(*new_field->item);
      new_field->item=all_fields.head_ref();
    }
  }
  DBUG_RETURN(0);
}

/*
12020 12021 12022
  Create a group by that consist of all non const fields. Try to use
  the fields in the order given by 'order' to allow one to optimize
  away 'order by'.
unknown's avatar
unknown committed
12023 12024 12025
*/

static ORDER *
12026 12027
create_distinct_group(THD *thd, ORDER *order_list, List<Item> &fields, 
		      bool *all_order_by_fields_used)
unknown's avatar
unknown committed
12028 12029 12030 12031 12032
{
  List_iterator<Item> li(fields);
  Item *item;
  ORDER *order,*group,**prev;

12033
  *all_order_by_fields_used= 1;
unknown's avatar
unknown committed
12034 12035 12036 12037 12038 12039 12040 12041
  while ((item=li++))
    item->marker=0;			/* Marker that field is not used */

  prev= &group;  group=0;
  for (order=order_list ; order; order=order->next)
  {
    if (order->in_field_list)
    {
12042
      ORDER *ord=(ORDER*) thd->memdup((char*) order,sizeof(ORDER));
unknown's avatar
unknown committed
12043 12044 12045 12046 12047 12048
      if (!ord)
	return 0;
      *prev=ord;
      prev= &ord->next;
      (*ord->item)->marker=1;
    }
12049 12050
    else
      *all_order_by_fields_used= 0;
unknown's avatar
unknown committed
12051 12052 12053 12054 12055 12056 12057 12058 12059
  }

  li.rewind();
  while ((item=li++))
  {
    if (item->const_item() || item->with_sum_func)
      continue;
    if (!item->marker)
    {
12060
      ORDER *ord=(ORDER*) thd->calloc(sizeof(ORDER));
unknown's avatar
unknown committed
12061 12062 12063 12064 12065 12066 12067 12068 12069 12070 12071 12072 12073 12074
      if (!ord)
	return 0;
      ord->item=li.ref();
      ord->asc=1;
      *prev=ord;
      prev= &ord->next;
    }
  }
  *prev=0;
  return group;
}


/*****************************************************************************
12075
  Update join with count of the different type of fields
unknown's avatar
unknown committed
12076 12077 12078
*****************************************************************************/

void
unknown's avatar
unknown committed
12079 12080
count_field_types(TMP_TABLE_PARAM *param, List<Item> &fields,
		  bool reset_with_sum_func)
unknown's avatar
unknown committed
12081 12082 12083 12084
{
  List_iterator<Item> li(fields);
  Item *field;

12085
  param->field_count=param->sum_func_count=param->func_count=
unknown's avatar
unknown committed
12086
    param->hidden_field_count=0;
unknown's avatar
unknown committed
12087 12088 12089 12090 12091 12092 12093 12094 12095 12096 12097 12098 12099 12100 12101 12102 12103 12104 12105 12106 12107 12108 12109 12110 12111
  param->quick_group=1;
  while ((field=li++))
  {
    Item::Type type=field->type();
    if (type == Item::FIELD_ITEM)
      param->field_count++;
    else if (type == Item::SUM_FUNC_ITEM)
    {
      if (! field->const_item())
      {
	Item_sum *sum_item=(Item_sum*) field;
	if (!sum_item->quick_group)
	  param->quick_group=0;			// UDF SUM function
	param->sum_func_count++;

	for (uint i=0 ; i < sum_item->arg_count ; i++)
	{
	  if (sum_item->args[0]->type() == Item::FIELD_ITEM)
	    param->field_count++;
	  else
	    param->func_count++;
	}
      }
    }
    else
unknown's avatar
unknown committed
12112
    {
unknown's avatar
unknown committed
12113
      param->func_count++;
unknown's avatar
unknown committed
12114 12115 12116
      if (reset_with_sum_func)
	field->with_sum_func=0;
    }
unknown's avatar
unknown committed
12117 12118 12119 12120 12121 12122 12123 12124 12125 12126 12127 12128 12129 12130 12131
  }
}


/*
  Return 1 if second is a subpart of first argument
  If first parts has different direction, change it to second part
  (group is sorted like order)
*/

static bool
test_if_subpart(ORDER *a,ORDER *b)
{
  for (; a && b; a=a->next,b=b->next)
  {
12132
    if ((*a->item)->eq(*b->item,1))
unknown's avatar
unknown committed
12133 12134 12135 12136 12137 12138 12139 12140 12141 12142 12143 12144 12145 12146 12147 12148 12149 12150 12151 12152 12153 12154 12155 12156 12157 12158
      a->asc=b->asc;
    else
      return 0;
  }
  return test(!b);
}

/*
  Return table number if there is only one table in sort order
  and group and order is compatible
  else return 0;
*/

static TABLE *
get_sort_by_table(ORDER *a,ORDER *b,TABLE_LIST *tables)
{
  table_map map= (table_map) 0;
  DBUG_ENTER("get_sort_by_table");

  if (!a)
    a=b;					// Only one need to be given
  else if (!b)
    b=a;

  for (; a && b; a=a->next,b=b->next)
  {
12159
    if (!(*a->item)->eq(*b->item,1))
unknown's avatar
unknown committed
12160 12161 12162
      DBUG_RETURN(0);
    map|=a->item[0]->used_tables();
  }
unknown's avatar
unknown committed
12163
  if (!map || (map & (RAND_TABLE_BIT | OUTER_REF_TABLE_BIT)))
unknown's avatar
unknown committed
12164 12165
    DBUG_RETURN(0);

12166
  for (; !(map & tables->table->map); tables= tables->next_leaf);
unknown's avatar
unknown committed
12167 12168 12169 12170 12171 12172 12173 12174 12175 12176 12177 12178
  if (map != tables->table->map)
    DBUG_RETURN(0);				// More than one table
  DBUG_PRINT("exit",("sort by table: %d",tables->table->tablenr));
  DBUG_RETURN(tables->table);
}


	/* calc how big buffer we need for comparing group entries */

static void
calc_group_buffer(JOIN *join,ORDER *group)
{
12179 12180
  uint key_length=0, parts=0, null_parts=0;

unknown's avatar
unknown committed
12181 12182 12183 12184
  if (group)
    join->group= 1;
  for (; group ; group=group->next)
  {
12185 12186
    Item *group_item= *group->item;
    Field *field= group_item->get_tmp_table_field();
unknown's avatar
unknown committed
12187 12188 12189 12190
    if (field)
    {
      if (field->type() == FIELD_TYPE_BLOB)
	key_length+=MAX_BLOB_WIDTH;		// Can't be used as a key
12191 12192
      else if (field->type() == MYSQL_TYPE_VARCHAR)
        key_length+= field->field_length + HA_KEY_BLOB_LENGTH;
unknown's avatar
unknown committed
12193
      else
12194
	key_length+= field->pack_length();
unknown's avatar
unknown committed
12195 12196
    }
    else
12197 12198 12199 12200 12201 12202 12203 12204 12205 12206 12207 12208 12209 12210 12211 12212 12213 12214 12215 12216 12217 12218 12219 12220 12221 12222
    { 
      switch (group_item->result_type()) {
      case REAL_RESULT:
        key_length+= sizeof(double);
        break;
      case INT_RESULT:
        key_length+= sizeof(longlong);
        break;
      case DECIMAL_RESULT:
        key_length+= my_decimal_get_binary_size(group_item->max_length - 
                                                (group_item->decimals ? 1 : 0),
                                                group_item->decimals);
        break;
      case STRING_RESULT:
        /*
          Group strings are taken as varstrings and require an length field.
          A field is not yet created by create_tmp_field()
          and the sizes should match up.
        */
        key_length+= group_item->max_length + HA_KEY_BLOB_LENGTH;
        break;
      default:
        /* This case should never be choosen */
        DBUG_ASSERT(0);
        join->thd->fatal_error();
      }
12223
    }
unknown's avatar
unknown committed
12224
    parts++;
12225
    if (group_item->maybe_null)
12226
      null_parts++;
unknown's avatar
unknown committed
12227
  }
12228
  join->tmp_table_param.group_length=key_length+null_parts;
unknown's avatar
unknown committed
12229
  join->tmp_table_param.group_parts=parts;
12230
  join->tmp_table_param.group_null_parts=null_parts;
unknown's avatar
unknown committed
12231 12232
}

12233

12234
/*
12235
  allocate group fields or take prepared (cached)
12236

12237
  SYNOPSIS
12238 12239 12240 12241 12242 12243 12244 12245 12246 12247 12248 12249
    make_group_fields()
    main_join - join of current select
    curr_join - current join (join of current select or temporary copy of it)

  RETURN
    0 - ok
    1 - failed
*/

static bool
make_group_fields(JOIN *main_join, JOIN *curr_join)
{
12250 12251 12252 12253 12254 12255 12256 12257 12258 12259 12260 12261
  if (main_join->group_fields_cache.elements)
  {
    curr_join->group_fields= main_join->group_fields_cache;
    curr_join->sort_and_group= 1;
  }
  else
  {
    if (alloc_group_fields(curr_join, curr_join->group_list))
      return (1);
    main_join->group_fields_cache= curr_join->group_fields;
  }
  return (0);
12262
}
unknown's avatar
unknown committed
12263

12264

unknown's avatar
unknown committed
12265
/*
12266 12267
  Get a list of buffers for saveing last group
  Groups are saved in reverse order for easyer check loop
unknown's avatar
unknown committed
12268 12269 12270 12271 12272 12273 12274 12275 12276
*/

static bool
alloc_group_fields(JOIN *join,ORDER *group)
{
  if (group)
  {
    for (; group ; group=group->next)
    {
unknown's avatar
unknown committed
12277
      Cached_item *tmp=new_Cached_item(join->thd, *group->item);
unknown's avatar
unknown committed
12278 12279 12280 12281 12282 12283 12284 12285 12286 12287
      if (!tmp || join->group_fields.push_front(tmp))
	return TRUE;
    }
  }
  join->sort_and_group=1;			/* Mark for do_select */
  return FALSE;
}


static int
unknown's avatar
unknown committed
12288
test_if_group_changed(List<Cached_item> &list)
unknown's avatar
unknown committed
12289
{
12290
  DBUG_ENTER("test_if_group_changed");
unknown's avatar
unknown committed
12291
  List_iterator<Cached_item> li(list);
unknown's avatar
unknown committed
12292
  int idx= -1,i;
unknown's avatar
unknown committed
12293
  Cached_item *buff;
unknown's avatar
unknown committed
12294 12295 12296 12297 12298 12299

  for (i=(int) list.elements-1 ; (buff=li++) ; i--)
  {
    if (buff->cmp())
      idx=i;
  }
12300 12301
  DBUG_PRINT("info", ("idx: %d", idx));
  DBUG_RETURN(idx);
unknown's avatar
unknown committed
12302 12303 12304 12305
}


/*
12306
  Setup copy_fields to save fields at start of new group
unknown's avatar
unknown committed
12307 12308 12309 12310 12311 12312 12313 12314 12315 12316 12317 12318 12319 12320 12321 12322 12323 12324 12325

  setup_copy_fields()
    thd - THD pointer
    param - temporary table parameters
    ref_pointer_array - array of pointers to top elements of filed list
    res_selected_fields - new list of items of select item list
    res_all_fields - new list of all items
    elements - number of elements in select item list
    all_fields - all fields list

  DESCRIPTION
    Setup copy_fields to save fields at start of new group
    Only FIELD_ITEM:s and FUNC_ITEM:s needs to be saved between groups.
    Change old item_field to use a new field with points at saved fieldvalue
    This function is only called before use of send_fields
  
  RETURN
    0 - ok
    !=0 - error
unknown's avatar
unknown committed
12326 12327 12328
*/

bool
12329 12330
setup_copy_fields(THD *thd, TMP_TABLE_PARAM *param,
		  Item **ref_pointer_array,
unknown's avatar
unknown committed
12331 12332
		  List<Item> &res_selected_fields, List<Item> &res_all_fields,
		  uint elements, List<Item> &all_fields)
unknown's avatar
unknown committed
12333 12334
{
  Item *pos;
unknown's avatar
unknown committed
12335
  List_iterator_fast<Item> li(all_fields);
12336
  Copy_field *copy= NULL;
unknown's avatar
unknown committed
12337 12338 12339
  res_selected_fields.empty();
  res_all_fields.empty();
  List_iterator_fast<Item> itr(res_all_fields);
12340
  List<Item> extra_funcs;
unknown's avatar
unknown committed
12341
  uint i, border= all_fields.elements - elements;
unknown's avatar
af  
unknown committed
12342
  DBUG_ENTER("setup_copy_fields");
unknown's avatar
unknown committed
12343

12344 12345
  if (param->field_count && 
      !(copy=param->copy_field= new Copy_field[param->field_count]))
12346
    goto err2;
unknown's avatar
unknown committed
12347 12348

  param->copy_funcs.empty();
12349
  for (i= 0; (pos= li++); i++)
unknown's avatar
unknown committed
12350 12351 12352
  {
    if (pos->type() == Item::FIELD_ITEM)
    {
12353
      Item_field *item;
unknown's avatar
af  
unknown committed
12354
      if (!(item= new Item_field(thd, ((Item_field*) pos))))
12355 12356
	goto err;
      pos= item;
unknown's avatar
unknown committed
12357 12358
      if (item->field->flags & BLOB_FLAG)
      {
12359
	if (!(pos= new Item_copy_string(pos)))
unknown's avatar
unknown committed
12360
	  goto err;
12361 12362 12363 12364 12365 12366 12367 12368 12369 12370
       /*
         Item_copy_string::copy for function can call 
         Item_copy_string::val_int for blob via Item_ref.
         But if Item_copy_string::copy for blob isn't called before,
         it's value will be wrong
         so let's insert Item_copy_string for blobs in the beginning of 
         copy_funcs
         (to see full test case look at having.test, BUG #4358) 
       */
	if (param->copy_funcs.push_front(pos))
unknown's avatar
unknown committed
12371 12372
	  goto err;
      }
12373 12374 12375 12376 12377 12378 12379
      else
      {
	/* 
	   set up save buffer and change result_field to point at 
	   saved value
	*/
	Field *field= item->field;
unknown's avatar
unknown committed
12380
	item->result_field=field->new_field(thd->mem_root,field->table);
12381 12382 12383
	char *tmp=(char*) sql_alloc(field->pack_length()+1);
	if (!tmp)
	  goto err;
12384 12385 12386 12387 12388 12389
      if (copy)
      {
        copy->set(tmp, item->result_field);
        item->result_field->move_field(copy->to_ptr,copy->to_null_ptr,1);
        copy++;
      }				
12390
      }
unknown's avatar
unknown committed
12391 12392
    }
    else if ((pos->type() == Item::FUNC_ITEM ||
12393 12394
	      pos->type() == Item::SUBSELECT_ITEM ||
	      pos->type() == Item::CACHE_ITEM ||
unknown's avatar
unknown committed
12395 12396 12397 12398 12399 12400 12401 12402 12403 12404 12405
	      pos->type() == Item::COND_ITEM) &&
	     !pos->with_sum_func)
    {						// Save for send fields
      /* TODO:
	 In most cases this result will be sent to the user.
	 This should be changed to use copy_int or copy_real depending
	 on how the value is to be used: In some cases this may be an
	 argument in a group function, like: IF(ISNULL(col),0,COUNT(*))
      */
      if (!(pos=new Item_copy_string(pos)))
	goto err;
12406 12407 12408 12409 12410 12411
      if (i < border)                           // HAVING, ORDER and GROUP BY
      {
        if (extra_funcs.push_back(pos))
          goto err;
      }
      else if (param->copy_funcs.push_back(pos))
unknown's avatar
unknown committed
12412 12413
	goto err;
    }
unknown's avatar
unknown committed
12414 12415
    res_all_fields.push_back(pos);
    ref_pointer_array[((i < border)? all_fields.elements-i-1 : i-border)]=
12416
      pos;
unknown's avatar
unknown committed
12417
  }
unknown's avatar
unknown committed
12418
  param->copy_field_end= copy;
12419 12420 12421

  for (i= 0; i < border; i++)
    itr++;
unknown's avatar
unknown committed
12422
  itr.sublist(res_selected_fields, elements);
12423 12424 12425 12426 12427 12428
  /*
    Put elements from HAVING, ORDER BY and GROUP BY last to ensure that any
    reference used in these will resolve to a item that is already calculated
  */
  param->copy_funcs.concat(&extra_funcs);

unknown's avatar
unknown committed
12429 12430 12431
  DBUG_RETURN(0);

 err:
12432 12433
  if (copy)
    delete [] param->copy_field;			// This is never 0
unknown's avatar
unknown committed
12434
  param->copy_field=0;
12435
err2:
unknown's avatar
unknown committed
12436 12437 12438 12439 12440
  DBUG_RETURN(TRUE);
}


/*
12441 12442 12443 12444
  Make a copy of all simple SELECT'ed items

  This is done at the start of a new group so that we can retrieve
  these later when the group changes.
unknown's avatar
unknown committed
12445 12446 12447 12448 12449 12450
*/

void
copy_fields(TMP_TABLE_PARAM *param)
{
  Copy_field *ptr=param->copy_field;
unknown's avatar
unknown committed
12451
  Copy_field *end=param->copy_field_end;
unknown's avatar
unknown committed
12452

12453
  for (; ptr != end; ptr++)
unknown's avatar
unknown committed
12454 12455
    (*ptr->do_copy)(ptr);

unknown's avatar
unknown committed
12456
  List_iterator_fast<Item> it(param->copy_funcs);
unknown's avatar
unknown committed
12457 12458 12459 12460 12461 12462
  Item_copy_string *item;
  while ((item = (Item_copy_string*) it++))
    item->copy();
}


12463 12464
/*
  Make an array of pointers to sum_functions to speed up sum_func calculation
unknown's avatar
unknown committed
12465

12466 12467 12468 12469 12470 12471 12472 12473 12474
  SYNOPSIS
    alloc_func_list()

  RETURN
    0	ok
    1	Error
*/

bool JOIN::alloc_func_list()
unknown's avatar
unknown committed
12475
{
12476 12477 12478 12479 12480 12481 12482 12483 12484 12485 12486 12487 12488 12489 12490 12491 12492 12493 12494 12495 12496 12497 12498 12499 12500 12501 12502
  uint func_count, group_parts;
  DBUG_ENTER("alloc_func_list");

  func_count= tmp_table_param.sum_func_count;
  /*
    If we are using rollup, we need a copy of the summary functions for
    each level
  */
  if (rollup.state != ROLLUP::STATE_NONE)
    func_count*= (send_group_parts+1);

  group_parts= send_group_parts;
  /*
    If distinct, reserve memory for possible
    disctinct->group_by optimization
  */
  if (select_distinct)
    group_parts+= fields_list.elements;

  /* This must use calloc() as rollup_make_fields depends on this */
  sum_funcs= (Item_sum**) thd->calloc(sizeof(Item_sum**) * (func_count+1) +
				      sizeof(Item_sum***) * (group_parts+1));
  sum_funcs_end= (Item_sum***) (sum_funcs+func_count+1);
  DBUG_RETURN(sum_funcs == 0);
}


unknown's avatar
af  
unknown committed
12503 12504 12505 12506 12507 12508 12509 12510
/*
  Initialize 'sum_funcs' array with all Item_sum objects

  SYNOPSIS
    make_sum_func_list()
    field_list		All items
    send_fields		Items in select list
    before_group_by	Set to 1 if this is called before GROUP BY handling
12511
    recompute           Set to TRUE if sum_funcs must be recomputed
unknown's avatar
af  
unknown committed
12512 12513 12514 12515 12516 12517

  RETURN
    0  ok
    1  error
*/

12518
bool JOIN::make_sum_func_list(List<Item> &field_list, List<Item> &send_fields,
12519
			      bool before_group_by, bool recompute)
unknown's avatar
unknown committed
12520
{
12521
  List_iterator_fast<Item> it(field_list);
12522 12523
  Item_sum **func;
  Item *item;
unknown's avatar
unknown committed
12524 12525
  DBUG_ENTER("make_sum_func_list");

12526 12527 12528
  if (*sum_funcs && !recompute)
    DBUG_RETURN(FALSE); /* We have already initialized sum_funcs. */

12529 12530
  func= sum_funcs;
  while ((item=it++))
unknown's avatar
unknown committed
12531
  {
12532 12533
    if (item->type() == Item::SUM_FUNC_ITEM && !item->const_item())
      *func++= (Item_sum*) item;
unknown's avatar
unknown committed
12534
  }
12535 12536 12537
  if (before_group_by && rollup.state == ROLLUP::STATE_INITED)
  {
    rollup.state= ROLLUP::STATE_READY;
12538
    if (rollup_make_fields(field_list, send_fields, &func))
12539 12540 12541 12542 12543 12544 12545
      DBUG_RETURN(TRUE);			// Should never happen
  }
  else if (rollup.state == ROLLUP::STATE_NONE)
  {
    for (uint i=0 ; i <= send_group_parts ;i++)
      sum_funcs_end[i]= func;
  }
12546 12547
  else if (rollup.state == ROLLUP::STATE_READY)
    DBUG_RETURN(FALSE);                         // Don't put end marker
unknown's avatar
unknown committed
12548 12549 12550 12551 12552 12553
  *func=0;					// End marker
  DBUG_RETURN(FALSE);
}


/*
unknown's avatar
af  
unknown committed
12554
  Change all funcs and sum_funcs to fields in tmp table, and create
unknown's avatar
unknown committed
12555 12556 12557 12558 12559 12560 12561 12562 12563 12564 12565 12566 12567
  new list of all items.

  change_to_use_tmp_fields()
    thd - THD pointer
    ref_pointer_array - array of pointers to top elements of filed list
    res_selected_fields - new list of items of select item list
    res_all_fields - new list of all items
    elements - number of elements in select item list
    all_fields - all fields list

   RETURN
    0 - ok
    !=0 - error
unknown's avatar
unknown committed
12568 12569 12570
*/

static bool
12571
change_to_use_tmp_fields(THD *thd, Item **ref_pointer_array,
unknown's avatar
unknown committed
12572 12573 12574
			 List<Item> &res_selected_fields,
			 List<Item> &res_all_fields,
			 uint elements, List<Item> &all_fields)
unknown's avatar
unknown committed
12575
{
unknown's avatar
unknown committed
12576
  List_iterator_fast<Item> it(all_fields);
unknown's avatar
unknown committed
12577
  Item *item_field,*item;
unknown's avatar
unknown committed
12578 12579
  DBUG_ENTER("change_to_use_tmp_fields");

unknown's avatar
unknown committed
12580 12581
  res_selected_fields.empty();
  res_all_fields.empty();
unknown's avatar
unknown committed
12582

unknown's avatar
unknown committed
12583
  uint i, border= all_fields.elements - elements;
12584
  for (i= 0; (item= it++); i++)
unknown's avatar
unknown committed
12585 12586
  {
    Field *field;
12587
    
unknown's avatar
unknown committed
12588
    if (item->with_sum_func && item->type() != Item::SUM_FUNC_ITEM)
12589 12590
      item_field= item;
    else
unknown's avatar
unknown committed
12591
    {
12592
      if (item->type() == Item::FIELD_ITEM)
unknown's avatar
unknown committed
12593
      {
12594
	item_field= item->get_tmp_table_item(thd);
unknown's avatar
unknown committed
12595
      }
12596
      else if ((field= item->get_tmp_table_field()))
12597 12598 12599 12600 12601 12602
      {
	if (item->type() == Item::SUM_FUNC_ITEM && field->table->group)
	  item_field= ((Item_sum*) item)->result_item(field);
	else
	  item_field= (Item*) new Item_field(field);
	if (!item_field)
unknown's avatar
unknown committed
12603 12604
	  DBUG_RETURN(TRUE);                    // Fatal error
	item_field->name= item->name;
12605 12606 12607 12608
#ifndef DBUG_OFF
	if (_db_on_ && !item_field->name)
	{
	  char buff[256];
12609
	  String str(buff,sizeof(buff),&my_charset_bin);
12610 12611 12612 12613
	  str.length(0);
	  item->print(&str);
	  item_field->name= sql_strmake(str.ptr(),str.length());
	}
unknown's avatar
unknown committed
12614
#endif
12615 12616 12617
      }
      else
	item_field= item;
unknown's avatar
unknown committed
12618 12619 12620
    }
    res_all_fields.push_back(item_field);
    ref_pointer_array[((i < border)? all_fields.elements-i-1 : i-border)]=
12621
      item_field;
unknown's avatar
unknown committed
12622
  }
12623

unknown's avatar
unknown committed
12624
  List_iterator_fast<Item> itr(res_all_fields);
12625 12626
  for (i= 0; i < border; i++)
    itr++;
unknown's avatar
unknown committed
12627
  itr.sublist(res_selected_fields, elements);
unknown's avatar
unknown committed
12628
  DBUG_RETURN(FALSE);
unknown's avatar
unknown committed
12629 12630 12631 12632
}


/*
12633 12634
  Change all sum_func refs to fields to point at fields in tmp table
  Change all funcs to be fields in tmp table
unknown's avatar
unknown committed
12635 12636 12637 12638 12639 12640 12641 12642 12643 12644

  change_refs_to_tmp_fields()
    thd - THD pointer
    ref_pointer_array - array of pointers to top elements of filed list
    res_selected_fields - new list of items of select item list
    res_all_fields - new list of all items
    elements - number of elements in select item list
    all_fields - all fields list

   RETURN
12645 12646
    0	ok
    1	error
unknown's avatar
unknown committed
12647 12648 12649
*/

static bool
12650
change_refs_to_tmp_fields(THD *thd, Item **ref_pointer_array,
unknown's avatar
unknown committed
12651 12652 12653
			  List<Item> &res_selected_fields,
			  List<Item> &res_all_fields, uint elements,
			  List<Item> &all_fields)
unknown's avatar
unknown committed
12654
{
unknown's avatar
unknown committed
12655
  List_iterator_fast<Item> it(all_fields);
12656
  Item *item, *new_item;
unknown's avatar
unknown committed
12657 12658
  res_selected_fields.empty();
  res_all_fields.empty();
unknown's avatar
unknown committed
12659

unknown's avatar
unknown committed
12660
  uint i, border= all_fields.elements - elements;
12661
  for (i= 0; (item= it++); i++)
unknown's avatar
unknown committed
12662
  {
unknown's avatar
unknown committed
12663 12664
    res_all_fields.push_back(new_item= item->get_tmp_table_item(thd));
    ref_pointer_array[((i < border)? all_fields.elements-i-1 : i-border)]=
12665
      new_item;
unknown's avatar
unknown committed
12666
  }
12667

unknown's avatar
unknown committed
12668
  List_iterator_fast<Item> itr(res_all_fields);
12669 12670
  for (i= 0; i < border; i++)
    itr++;
unknown's avatar
unknown committed
12671
  itr.sublist(res_selected_fields, elements);
12672

12673
  return thd->is_fatal_error;
unknown's avatar
unknown committed
12674 12675 12676 12677 12678
}



/******************************************************************************
12679
  Code for calculating functions
unknown's avatar
unknown committed
12680 12681
******************************************************************************/

12682 12683 12684 12685 12686 12687 12688 12689 12690 12691 12692 12693 12694 12695 12696 12697 12698

/*
  Call ::setup for all sum functions

  SYNOPSIS
    setup_sum_funcs()
    thd           thread handler
    func_ptr      sum function list

  RETURN
    FALSE  ok
    TRUE   error
*/

static bool setup_sum_funcs(THD *thd, Item_sum **func_ptr)
{
  Item_sum *func;
unknown's avatar
unknown committed
12699
  DBUG_ENTER("setup_sum_funcs");
12700
  while ((func= *(func_ptr++)))
unknown's avatar
unknown committed
12701
  {
12702
    if (func->setup(thd))
unknown's avatar
unknown committed
12703
      DBUG_RETURN(TRUE);
unknown's avatar
unknown committed
12704
  }
unknown's avatar
unknown committed
12705
  DBUG_RETURN(FALSE);
12706 12707 12708
}


unknown's avatar
unknown committed
12709 12710 12711 12712 12713 12714 12715 12716 12717 12718 12719 12720 12721 12722 12723 12724 12725
static void
init_tmptable_sum_functions(Item_sum **func_ptr)
{
  Item_sum *func;
  while ((func= *(func_ptr++)))
    func->reset_field();
}


	/* Update record 0 in tmp_table from record 1 */

static void
update_tmptable_sum_func(Item_sum **func_ptr,
			 TABLE *tmp_table __attribute__((unused)))
{
  Item_sum *func;
  while ((func= *(func_ptr++)))
unknown's avatar
unknown committed
12726
    func->update_field();
unknown's avatar
unknown committed
12727 12728 12729 12730 12731 12732
}


	/* Copy result of sum functions to record in tmp_table */

static void
unknown's avatar
unknown committed
12733
copy_sum_funcs(Item_sum **func_ptr, Item_sum **end_ptr)
unknown's avatar
unknown committed
12734
{
unknown's avatar
unknown committed
12735 12736
  for (; func_ptr != end_ptr ; func_ptr++)
    (void) (*func_ptr)->save_in_result_field(1);
unknown's avatar
unknown committed
12737 12738 12739 12740
  return;
}


12741 12742
static bool
init_sum_functions(Item_sum **func_ptr, Item_sum **end_ptr)
unknown's avatar
unknown committed
12743
{
12744 12745 12746 12747 12748 12749 12750 12751 12752 12753 12754 12755
  for (; func_ptr != end_ptr ;func_ptr++)
  {
    if ((*func_ptr)->reset())
      return 1;
  }
  /* If rollup, calculate the upper sum levels */
  for ( ; *func_ptr ; func_ptr++)
  {
    if ((*func_ptr)->add())
      return 1;
  }
  return 0;
unknown's avatar
unknown committed
12756 12757 12758 12759 12760 12761 12762 12763 12764 12765 12766 12767 12768 12769 12770 12771
}


static bool
update_sum_func(Item_sum **func_ptr)
{
  Item_sum *func;
  for (; (func= (Item_sum*) *func_ptr) ; func_ptr++)
    if (func->add())
      return 1;
  return 0;
}

	/* Copy result of functions to record in tmp_table */

void
unknown's avatar
unknown committed
12772
copy_funcs(Item **func_ptr)
unknown's avatar
unknown committed
12773
{
unknown's avatar
unknown committed
12774
  Item *func;
unknown's avatar
unknown committed
12775
  for (; (func = *func_ptr) ; func_ptr++)
unknown's avatar
unknown committed
12776
    func->save_in_result_field(1);
unknown's avatar
unknown committed
12777 12778 12779
}


12780
/*
12781 12782
  Create a condition for a const reference and add this to the
  currenct select for the table
12783
*/
unknown's avatar
unknown committed
12784 12785 12786 12787 12788 12789 12790 12791 12792 12793 12794 12795 12796 12797 12798

static bool add_ref_to_table_cond(THD *thd, JOIN_TAB *join_tab)
{
  DBUG_ENTER("add_ref_to_table_cond");
  if (!join_tab->ref.key_parts)
    DBUG_RETURN(FALSE);

  Item_cond_and *cond=new Item_cond_and();
  TABLE *table=join_tab->table;
  int error;
  if (!cond)
    DBUG_RETURN(TRUE);

  for (uint i=0 ; i < join_tab->ref.key_parts ; i++)
  {
12799 12800
    Field *field=table->field[table->key_info[join_tab->ref.key].key_part[i].
			      fieldnr-1];
unknown's avatar
unknown committed
12801
    Item *value=join_tab->ref.items[i];
unknown's avatar
af  
unknown committed
12802
    cond->add(new Item_func_equal(new Item_field(field), value));
unknown's avatar
unknown committed
12803
  }
12804
  if (thd->is_fatal_error)
unknown's avatar
unknown committed
12805
    DBUG_RETURN(TRUE);
12806

unknown's avatar
unknown committed
12807 12808
  if (!cond->fixed)
    cond->fix_fields(thd,(TABLE_LIST *) 0, (Item**)&cond);
unknown's avatar
unknown committed
12809 12810 12811 12812 12813
  if (join_tab->select)
  {
    error=(int) cond->add(join_tab->select->cond);
    join_tab->select_cond=join_tab->select->cond=cond;
  }
unknown's avatar
unknown committed
12814 12815
  else if ((join_tab->select= make_select(join_tab->table, 0, 0, cond, 0,
                                          &error)))
unknown's avatar
unknown committed
12816 12817 12818 12819 12820
    join_tab->select_cond=cond;

  DBUG_RETURN(error ? TRUE : FALSE);
}

12821 12822 12823 12824 12825 12826 12827 12828 12829 12830 12831 12832 12833 12834 12835 12836 12837

/*
  Free joins of subselect of this select.

  free_underlaid_joins()
    thd - THD pointer
    select - pointer to st_select_lex which subselects joins we will free
*/

void free_underlaid_joins(THD *thd, SELECT_LEX *select)
{
  for (SELECT_LEX_UNIT *unit= select->first_inner_unit();
       unit;
       unit= unit->next_unit())
    unit->cleanup();
}

unknown's avatar
unknown committed
12838
/****************************************************************************
12839 12840 12841
  ROLLUP handling
****************************************************************************/

unknown's avatar
unknown committed
12842 12843 12844 12845 12846 12847 12848 12849 12850 12851 12852 12853 12854 12855 12856 12857 12858 12859 12860 12861 12862 12863 12864 12865 12866 12867 12868 12869 12870 12871 12872 12873 12874
/*
  Replace occurences of group by fields in an expression by ref items

  SYNOPSIS
    change_group_ref()
    thd                  reference to the context
    expr                 expression to make replacement
    group_list           list of references to group by items
    changed        out:  returns 1 if item contains a replaced field item 
     
  DESCRIPTION
    The function replaces occurrences of group by fields in expr
    by ref objects for these fields unless they are under aggregate
    functions.

  IMPLEMENTATION
    The function recursively traverses the tree of the expr expression,
    looks for occurrences of the group by fields that are not under
    aggregate functions and replaces them for the corresponding ref items.

  NOTES
    This substitution is needed GROUP BY queries with ROLLUP if
    SELECT list contains expressions over group by attributes.

  EXAMPLES
    SELECT a+1 FROM t1 GROUP BY a WITH ROLLUP
    SELECT SUM(a)+a FROM t1 GROUP BY a WITH ROLLUP 
    
  RETURN
    0	if ok
    1   on error
*/

unknown's avatar
unknown committed
12875
static bool change_group_ref(THD *thd, Item_func *expr, ORDER *group_list,
unknown's avatar
unknown committed
12876 12877
                             bool *changed)
{
unknown's avatar
unknown committed
12878
  if (expr->arg_count)
unknown's avatar
unknown committed
12879 12880
  {
    Item **arg,**arg_end;
unknown's avatar
unknown committed
12881 12882
    for (arg= expr->arguments(),
         arg_end= expr->arguments()+expr->arg_count;
unknown's avatar
unknown committed
12883 12884 12885 12886 12887 12888 12889 12890 12891 12892 12893 12894 12895 12896 12897 12898 12899 12900 12901 12902
         arg != arg_end; arg++)
    {
      Item *item= *arg;
      if (item->type() == Item::FIELD_ITEM || item->type() == Item::REF_ITEM)
      {
        ORDER *group_tmp;
        for (group_tmp= group_list; group_tmp; group_tmp= group_tmp->next)
        {
          if (item->eq(*group_tmp->item,0))
          {
            Item *new_item;    
            if(!(new_item= new Item_ref(group_tmp->item, 0, item->name)))
              return 1;                                 // fatal_error is set
            thd->change_item_tree(arg, new_item);
            *changed= TRUE;
          }
        }
      }
      else if (item->type() == Item::FUNC_ITEM)
      {
unknown's avatar
unknown committed
12903
        if (change_group_ref(thd, (Item_func *) item, group_list, changed))
unknown's avatar
unknown committed
12904 12905 12906 12907 12908 12909 12910 12911
          return 1;
      }
    }
  }
  return 0;
}


12912 12913 12914 12915 12916 12917 12918 12919 12920 12921 12922 12923 12924 12925 12926 12927
/* Allocate memory needed for other rollup functions */

bool JOIN::rollup_init()
{
  uint i,j;
  Item **ref_array;

  tmp_table_param.quick_group= 0;	// Can't create groups in tmp table
  rollup.state= ROLLUP::STATE_INITED;

  /*
    Create pointers to the different sum function groups
    These are updated by rollup_make_fields()
  */
  tmp_table_param.group_parts= send_group_parts;

unknown's avatar
unknown committed
12928 12929 12930 12931 12932
  if (!(rollup.null_items= (Item_null_result**) thd->alloc((sizeof(Item*) +
                                                sizeof(Item**) +
                                                sizeof(List<Item>) +
				                ref_pointer_array_size)
				                * send_group_parts )))
12933
    return 1;
unknown's avatar
unknown committed
12934 12935
  
  rollup.fields= (List<Item>*) (rollup.null_items + send_group_parts);
12936 12937 12938 12939 12940 12941 12942 12943 12944
  rollup.ref_pointer_arrays= (Item***) (rollup.fields + send_group_parts);
  ref_array= (Item**) (rollup.ref_pointer_arrays+send_group_parts);

  /*
    Prepare space for field list for the different levels
    These will be filled up in rollup_make_fields()
  */
  for (i= 0 ; i < send_group_parts ; i++)
  {
unknown's avatar
unknown committed
12945
    rollup.null_items[i]= new (thd->mem_root) Item_null_result();
12946 12947
    List<Item> *rollup_fields= &rollup.fields[i];
    rollup_fields->empty();
12948 12949
    rollup.ref_pointer_arrays[i]= ref_array;
    ref_array+= all_fields.elements;
unknown's avatar
unknown committed
12950 12951 12952
  }
  for (i= 0 ; i < send_group_parts; i++)
  {
12953
    for (j=0 ; j < fields_list.elements ; j++)
unknown's avatar
unknown committed
12954
      rollup.fields[i].push_back(rollup.null_items[i]);
12955
  }
unknown's avatar
unknown committed
12956
  List_iterator_fast<Item> it(all_fields);
unknown's avatar
unknown committed
12957 12958 12959 12960 12961 12962
  Item *item;
  while ((item= it++))
  {
    ORDER *group_tmp;
    for (group_tmp= group_list; group_tmp; group_tmp= group_tmp->next)
    {
unknown's avatar
unknown committed
12963
      if (item->eq(*group_tmp->item,0))
unknown's avatar
unknown committed
12964 12965
        item->maybe_null= 1;
    }
unknown's avatar
unknown committed
12966 12967 12968
    if (item->type() == Item::FUNC_ITEM)
    {
      bool changed= 0;
unknown's avatar
unknown committed
12969
      if (change_group_ref(thd, (Item_func *) item, group_list, &changed))
unknown's avatar
unknown committed
12970 12971 12972 12973 12974 12975 12976 12977 12978
        return 1;
      /*
        We have to prevent creation of a field in a temporary table for
        an expression that contains GROUP BY attributes.
        Marking the expression item as 'with_sum_func' will ensure this.
      */ 
      if (changed)
        item->with_sum_func= 1;
    }
unknown's avatar
unknown committed
12979
  }
12980 12981 12982 12983 12984 12985 12986 12987 12988
  return 0;
}
  

/*
  Fill up rollup structures with pointers to fields to use

  SYNOPSIS
    rollup_make_fields()
12989 12990
    fields_arg			List of all fields (hidden and real ones)
    sel_fields			Pointer to selected fields
12991 12992 12993 12994 12995 12996 12997 12998 12999 13000 13001
    func			Store here a pointer to all fields

  IMPLEMENTATION:
    Creates copies of item_sum items for each sum level

  RETURN
    0	if ok
	In this case func is pointing to next not used element.
    1   on error
*/

13002
bool JOIN::rollup_make_fields(List<Item> &fields_arg, List<Item> &sel_fields,
13003 13004
			      Item_sum ***func)
{
13005 13006
  List_iterator_fast<Item> it(fields_arg);
  Item *first_field= sel_fields.head();
13007 13008 13009 13010 13011 13012 13013 13014 13015 13016 13017 13018 13019 13020 13021 13022 13023 13024 13025 13026 13027 13028 13029
  uint level;

  /*
    Create field lists for the different levels

    The idea here is to have a separate field list for each rollup level to
    avoid all runtime checks of which columns should be NULL.

    The list is stored in reverse order to get sum function in such an order
    in func that it makes it easy to reset them with init_sum_functions()

    Assuming:  SELECT a, b, c SUM(b) FROM t1 GROUP BY a,b WITH ROLLUP

    rollup.fields[0] will contain list where a,b,c is NULL
    rollup.fields[1] will contain list where b,c is NULL
    ...
    rollup.ref_pointer_array[#] points to fields for rollup.fields[#]
    ...
    sum_funcs_end[0] points to all sum functions
    sum_funcs_end[1] points to all sum functions, except grand totals
    ...
  */

13030
  for (level=0 ; level < send_group_parts ; level++)
13031 13032 13033 13034 13035 13036 13037 13038 13039 13040
  {
    uint i;
    uint pos= send_group_parts - level -1;
    bool real_fields= 0;
    Item *item;
    List_iterator<Item> new_it(rollup.fields[pos]);
    Item **ref_array_start= rollup.ref_pointer_arrays[pos];
    ORDER *start_group;

    /* Point to first hidden field */
13041
    Item **ref_array= ref_array_start + fields_arg.elements-1;
13042 13043 13044 13045 13046 13047 13048 13049 13050 13051 13052 13053 13054 13055 13056 13057 13058 13059 13060 13061 13062 13063 13064 13065 13066 13067 13068 13069 13070 13071 13072 13073 13074 13075

    /* Remember where the sum functions ends for the previous level */
    sum_funcs_end[pos+1]= *func;

    /* Find the start of the group for this level */
    for (i= 0, start_group= group_list ;
	 i++ < pos ;
	 start_group= start_group->next)
      ;

    it.rewind();
    while ((item= it++))
    {
      if (item == first_field)
      {
	real_fields= 1;				// End of hidden fields
	ref_array= ref_array_start;
      }

      if (item->type() == Item::SUM_FUNC_ITEM && !item->const_item())
      {
	/*
	  This is a top level summary function that must be replaced with
	  a sum function that is reset for this level.

	  NOTE: This code creates an object which is not that nice in a
	  sub select.  Fortunately it's not common to have rollup in
	  sub selects.
	*/
	item= item->copy_or_same(thd);
	((Item_sum*) item)->make_unique();
	*(*func)= (Item_sum*) item;
	(*func)++;
      }
unknown's avatar
unknown committed
13076
      else 
13077 13078
      {
	/* Check if this is something that is part of this group by */
13079
	ORDER *group_tmp;
unknown's avatar
unknown committed
13080
	for (group_tmp= start_group, i= pos ;
unknown's avatar
unknown committed
13081
             group_tmp ; group_tmp= group_tmp->next, i++)
13082
	{
unknown's avatar
unknown committed
13083
          if (item->eq(*group_tmp->item,0))
13084 13085 13086 13087 13088
	  {
	    /*
	      This is an element that is used by the GROUP BY and should be
	      set to NULL in this level
	    */
unknown's avatar
unknown committed
13089 13090 13091
            Item_null_result *null_item= new (thd->mem_root) Item_null_result();
            if (!null_item)
              return 1;
13092
	    item->maybe_null= 1;		// Value will be null sometimes
13093
            null_item->result_field= item->get_tmp_table_field();
unknown's avatar
unknown committed
13094
            item= null_item;
13095 13096 13097 13098 13099 13100 13101 13102 13103 13104 13105 13106 13107 13108 13109 13110 13111 13112 13113 13114 13115 13116 13117 13118 13119 13120 13121 13122 13123 13124 13125 13126 13127 13128 13129 13130 13131 13132 13133 13134 13135 13136 13137 13138 13139 13140 13141 13142
	    break;
	  }
	}
      }
      *ref_array= item;
      if (real_fields)
      {
	(void) new_it++;			// Point to next item
	new_it.replace(item);			// Replace previous
	ref_array++;
      }
      else
	ref_array--;
    }
  }
  sum_funcs_end[0]= *func;			// Point to last function
  return 0;
}

/*
  Send all rollup levels higher than the current one to the client

  SYNOPSIS:
    rollup_send_data()
    idx			Level we are on:
			0 = Total sum level
			1 = First group changed  (a)
			2 = Second group changed (a,b)

  SAMPLE
    SELECT a, b, c SUM(b) FROM t1 GROUP BY a,b WITH ROLLUP

  RETURN
    0	ok
    1   If send_data_failed()
*/

int JOIN::rollup_send_data(uint idx)
{
  uint i;
  for (i= send_group_parts ; i-- > idx ; )
  {
    /* Get reference pointers to sum functions in place */
    memcpy((char*) ref_pointer_array,
	   (char*) rollup.ref_pointer_arrays[i],
	   ref_pointer_array_size);
    if ((!having || having->val_int()))
    {
unknown's avatar
unknown committed
13143
      if (send_records < unit->select_limit_cnt && do_send_rows &&
13144 13145 13146 13147 13148 13149 13150 13151 13152 13153
	  result->send_data(rollup.fields[i]))
	return 1;
      send_records++;
    }
  }
  /* Restore ref_pointer_array */
  set_items_ref_array(current_ref_pointer_array);
  return 0;
}

unknown's avatar
unknown committed
13154 13155 13156 13157 13158 13159 13160 13161 13162 13163 13164 13165 13166 13167 13168 13169 13170 13171 13172 13173 13174 13175 13176 13177 13178 13179 13180 13181 13182 13183 13184 13185 13186 13187 13188 13189 13190 13191 13192 13193 13194 13195 13196 13197 13198 13199 13200 13201 13202 13203 13204 13205
/*
  Write all rollup levels higher than the current one to a temp table

  SYNOPSIS:
    rollup_write_data()
    idx                 Level we are on:
                        0 = Total sum level
                        1 = First group changed  (a)
                        2 = Second group changed (a,b)
    table               reference to temp table

  SAMPLE
    SELECT a, b, SUM(c) FROM t1 GROUP BY a,b WITH ROLLUP

  RETURN
    0	ok
    1   if write_data_failed()
*/

int JOIN::rollup_write_data(uint idx, TABLE *table)
{
  uint i;
  for (i= send_group_parts ; i-- > idx ; )
  {
    /* Get reference pointers to sum functions in place */
    memcpy((char*) ref_pointer_array,
	   (char*) rollup.ref_pointer_arrays[i],
	   ref_pointer_array_size);
    if ((!having || having->val_int()))
    {
      int error;
      Item *item;
      List_iterator_fast<Item> it(rollup.fields[i]);
      while ((item= it++))
      {
        if (item->type() == Item::NULL_ITEM && item->is_result_field())
          item->save_in_result_field(1);
      }
      copy_sum_funcs(sum_funcs_end[i+1], sum_funcs_end[i]);
      if ((error= table->file->write_row(table->record[0])))
      {
	if (create_myisam_from_heap(thd, table, &tmp_table_param,
				      error, 0))
	  return 1;		     
      }
    }
  }
  /* Restore ref_pointer_array */
  set_items_ref_array(current_ref_pointer_array);
  return 0;
}

13206 13207 13208 13209 13210 13211 13212 13213 13214 13215 13216 13217 13218 13219 13220 13221 13222 13223 13224 13225
/*
  clear results if there are not rows found for group
  (end_send_group/end_write_group)

  SYNOPSYS
     JOIN::clear()
*/

void JOIN::clear()
{
  clear_tables(this);
  copy_fields(&tmp_table_param);

  if (sum_funcs)
  {
    Item_sum *func, **func_ptr= sum_funcs;
    while ((func= *(func_ptr++)))
      func->clear();
  }
}
13226

unknown's avatar
unknown committed
13227
/****************************************************************************
13228 13229
  EXPLAIN handling

13230
  Send a description about what how the select will be done to stdout
unknown's avatar
unknown committed
13231 13232
****************************************************************************/

unknown's avatar
unknown committed
13233
static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
unknown's avatar
unknown committed
13234
			    bool distinct,const char *message)
unknown's avatar
unknown committed
13235 13236
{
  List<Item> field_list;
13237
  List<Item> item_list;
unknown's avatar
unknown committed
13238
  THD *thd=join->thd;
13239
  select_result *result=join->result;
13240
  Item *item_null= new Item_null();
unknown's avatar
af  
unknown committed
13241 13242
  CHARSET_INFO *cs= system_charset_info;
  int quick_type;
unknown's avatar
unknown committed
13243
  DBUG_ENTER("select_describe");
13244
  DBUG_PRINT("info", ("Select 0x%lx, type %s, message %s",
unknown's avatar
unknown committed
13245
		      (ulong)join->select_lex, join->select_lex->type,
13246
		      message ? message : "NULL"));
13247
  /* Don't log this into the slow query log */
13248
  thd->server_status&= ~(SERVER_QUERY_NO_INDEX_USED | SERVER_QUERY_NO_GOOD_INDEX_USED);
unknown's avatar
unknown committed
13249
  join->unit->offset_limit_cnt= 0;
13250

unknown's avatar
unknown committed
13251
  if (message)
unknown's avatar
unknown committed
13252
  {
unknown's avatar
af  
unknown committed
13253 13254
    item_list.push_back(new Item_int((int32)
				     join->select_lex->select_number));
unknown's avatar
unknown committed
13255
    item_list.push_back(new Item_string(join->select_lex->type,
unknown's avatar
unknown committed
13256
					strlen(join->select_lex->type), cs));
13257
    for (uint i=0 ; i < 7; i++)
13258
      item_list.push_back(item_null);
unknown's avatar
unknown committed
13259
    item_list.push_back(new Item_string(message,strlen(message),cs));
13260
    if (result->send_data(item_list))
13261
      join->error= 1;
unknown's avatar
unknown committed
13262
  }
unknown's avatar
af  
unknown committed
13263 13264 13265 13266 13267 13268 13269 13270 13271 13272 13273 13274 13275 13276 13277 13278 13279 13280 13281 13282 13283 13284 13285 13286 13287 13288 13289 13290 13291 13292 13293 13294 13295 13296 13297 13298 13299 13300 13301 13302 13303 13304 13305 13306 13307 13308 13309 13310 13311 13312 13313 13314 13315 13316 13317 13318 13319 13320 13321 13322 13323 13324 13325 13326
  else if (join->select_lex == join->unit->fake_select_lex)
  {
    /* 
      here we assume that the query will return at least two rows, so we
      show "filesort" in EXPLAIN. Of course, sometimes we'll be wrong
      and no filesort will be actually done, but executing all selects in
      the UNION to provide precise EXPLAIN information will hardly be
      appreciated :)
    */
    char table_name_buffer[NAME_LEN];
    item_list.empty();
    /* id */
    item_list.push_back(new Item_null);
    /* select_type */
    item_list.push_back(new Item_string(join->select_lex->type,
					strlen(join->select_lex->type),
					cs));
    /* table */
    {
      SELECT_LEX *sl= join->unit->first_select();
      uint len= 6, lastop= 0;
      memcpy(table_name_buffer, "<union", 6);
      for (; sl && len + lastop + 5 < NAME_LEN; sl= sl->next_select())
      {
        len+= lastop;
        lastop= my_snprintf(table_name_buffer + len, NAME_LEN - len,
                            "%u,", sl->select_number);
      }
      if (sl || len + lastop >= NAME_LEN)
      {
        memcpy(table_name_buffer + len, "...>", 5);
        len+= 4;
      }
      else
      {
        len+= lastop;
        table_name_buffer[len - 1]= '>';  // change ',' to '>'
      }
      item_list.push_back(new Item_string(table_name_buffer, len, cs));
    }
    /* type */
    item_list.push_back(new Item_string(join_type_str[JT_ALL],
					  strlen(join_type_str[JT_ALL]),
					  cs));
    /* possible_keys */
    item_list.push_back(item_null);
    /* key*/
    item_list.push_back(item_null);
    /* key_len */
    item_list.push_back(item_null);
    /* ref */
    item_list.push_back(item_null);
    /* rows */
    item_list.push_back(item_null);
    /* extra */
    if (join->unit->global_parameters->order_list.first)
      item_list.push_back(new Item_string("Using filesort",
					  14, cs));
    else
      item_list.push_back(new Item_string("", 0, cs));

    if (result->send_data(item_list))
      join->error= 1;
  }
unknown's avatar
unknown committed
13327 13328 13329 13330
  else
  {
    table_map used_tables=0;
    for (uint i=0 ; i < join->tables ; i++)
unknown's avatar
unknown committed
13331
    {
unknown's avatar
unknown committed
13332 13333
      JOIN_TAB *tab=join->join_tab+i;
      TABLE *table=tab->table;
unknown's avatar
af  
unknown committed
13334
      char buff[512]; 
unknown's avatar
unknown committed
13335 13336
      char buff1[512], buff2[512], buff3[512];
      char keylen_str_buf[64];
unknown's avatar
af  
unknown committed
13337 13338
      String extra(buff, sizeof(buff),cs);
      char table_name_buffer[NAME_LEN];
unknown's avatar
unknown committed
13339 13340
      String tmp1(buff1,sizeof(buff1),cs);
      String tmp2(buff2,sizeof(buff2),cs);
unknown's avatar
unknown committed
13341
      String tmp3(buff3,sizeof(buff3),cs);
unknown's avatar
af  
unknown committed
13342
      extra.length(0);
13343 13344
      tmp1.length(0);
      tmp2.length(0);
unknown's avatar
unknown committed
13345
      tmp3.length(0);
13346

unknown's avatar
af  
unknown committed
13347
      quick_type= -1;
unknown's avatar
unknown committed
13348
      item_list.empty();
unknown's avatar
af  
unknown committed
13349 13350
      /* id */
      item_list.push_back(new Item_uint((uint32)
unknown's avatar
unknown committed
13351
				       join->select_lex->select_number));
unknown's avatar
af  
unknown committed
13352
      /* select_type */
unknown's avatar
unknown committed
13353 13354
      item_list.push_back(new Item_string(join->select_lex->type,
					  strlen(join->select_lex->type),
unknown's avatar
unknown committed
13355
					  cs));
unknown's avatar
unknown committed
13356
      if (tab->type == JT_ALL && tab->select && tab->select->quick)
unknown's avatar
unknown committed
13357
      {
unknown's avatar
af  
unknown committed
13358 13359 13360 13361
        quick_type= tab->select->quick->get_type();
        if ((quick_type == QUICK_SELECT_I::QS_TYPE_INDEX_MERGE) ||
            (quick_type == QUICK_SELECT_I::QS_TYPE_ROR_INTERSECT) ||
            (quick_type == QUICK_SELECT_I::QS_TYPE_ROR_UNION))
unknown's avatar
unknown committed
13362 13363 13364 13365
          tab->type = JT_INDEX_MERGE;
        else
	  tab->type = JT_RANGE;
      }
unknown's avatar
af  
unknown committed
13366
      /* table */
unknown's avatar
unknown committed
13367
      if (table->derived_select_number)
unknown's avatar
unknown committed
13368
      {
unknown's avatar
unknown committed
13369
	/* Derived table name generation */
unknown's avatar
af  
unknown committed
13370
	int len= my_snprintf(table_name_buffer, sizeof(table_name_buffer)-1,
unknown's avatar
unknown committed
13371
			     "<derived%u>",
unknown's avatar
unknown committed
13372
			     table->derived_select_number);
unknown's avatar
af  
unknown committed
13373
	item_list.push_back(new Item_string(table_name_buffer, len, cs));
unknown's avatar
unknown committed
13374 13375
      }
      else
13376 13377
	item_list.push_back(new Item_string(table->alias,
					    strlen(table->alias),
unknown's avatar
unknown committed
13378
					    cs));
unknown's avatar
af  
unknown committed
13379
      /* type */
13380 13381
      item_list.push_back(new Item_string(join_type_str[tab->type],
					  strlen(join_type_str[tab->type]),
unknown's avatar
unknown committed
13382
					  cs));
unknown's avatar
af  
unknown committed
13383
      /* Build "possible_keys" value and add it to item_list */
13384
      if (!tab->keys.is_clear_all())
unknown's avatar
unknown committed
13385
      {
unknown's avatar
unknown committed
13386
        uint j;
13387
        for (j=0 ; j < table->s->keys ; j++)
13388 13389 13390 13391 13392
        {
          if (tab->keys.is_set(j))
          {
            if (tmp1.length())
              tmp1.append(',');
unknown's avatar
af  
unknown committed
13393 13394 13395
            tmp1.append(table->key_info[j].name, 
			strlen(table->key_info[j].name),
			system_charset_info);
13396 13397
          }
        }
unknown's avatar
unknown committed
13398
      }
13399
      if (tmp1.length())
unknown's avatar
unknown committed
13400
	item_list.push_back(new Item_string(tmp1.ptr(),tmp1.length(),cs));
unknown's avatar
unknown committed
13401
      else
13402
	item_list.push_back(item_null);
unknown's avatar
af  
unknown committed
13403 13404

      /* Build "key", "key_len", and "ref" values and add them to item_list */
unknown's avatar
unknown committed
13405
      if (tab->ref.key_parts)
unknown's avatar
unknown committed
13406
      {
13407
	KEY *key_info=table->key_info+ tab->ref.key;
unknown's avatar
unknown committed
13408
        register uint length;
13409
	item_list.push_back(new Item_string(key_info->name,
13410 13411
					    strlen(key_info->name),
					    system_charset_info));
unknown's avatar
unknown committed
13412 13413 13414 13415
        length= longlong2str(tab->ref.key_length, keylen_str_buf, 10) - 
                keylen_str_buf;
        item_list.push_back(new Item_string(keylen_str_buf, length,
                                            system_charset_info));
unknown's avatar
unknown committed
13416 13417
	for (store_key **ref=tab->ref.key_copy ; *ref ; ref++)
	{
13418 13419
	  if (tmp2.length())
	    tmp2.append(',');
unknown's avatar
af  
unknown committed
13420 13421
	  tmp2.append((*ref)->name(), strlen((*ref)->name()),
		      system_charset_info);
unknown's avatar
unknown committed
13422
	}
unknown's avatar
unknown committed
13423
	item_list.push_back(new Item_string(tmp2.ptr(),tmp2.length(),cs));
unknown's avatar
unknown committed
13424 13425 13426
      }
      else if (tab->type == JT_NEXT)
      {
13427
	KEY *key_info=table->key_info+ tab->index;
unknown's avatar
unknown committed
13428
        register uint length;
13429
	item_list.push_back(new Item_string(key_info->name,
unknown's avatar
unknown committed
13430
					    strlen(key_info->name),cs));
unknown's avatar
unknown committed
13431 13432 13433 13434 13435
        length= longlong2str(key_info->key_length, keylen_str_buf, 10) - 
                keylen_str_buf;
        item_list.push_back(new Item_string(keylen_str_buf, 
                                            length,
                                            system_charset_info));
13436
	item_list.push_back(item_null);
unknown's avatar
unknown committed
13437 13438 13439
      }
      else if (tab->select && tab->select->quick)
      {
unknown's avatar
af  
unknown committed
13440
        tab->select->quick->add_keys_and_lengths(&tmp2, &tmp3);
unknown's avatar
unknown committed
13441
	item_list.push_back(new Item_string(tmp2.ptr(),tmp2.length(),cs));
unknown's avatar
af  
unknown committed
13442
	item_list.push_back(new Item_string(tmp3.ptr(),tmp3.length(),cs));
13443
	item_list.push_back(item_null);
unknown's avatar
unknown committed
13444 13445 13446
      }
      else
      {
13447 13448 13449
	item_list.push_back(item_null);
	item_list.push_back(item_null);
	item_list.push_back(item_null);
unknown's avatar
unknown committed
13450
      }
unknown's avatar
af  
unknown committed
13451
      /* Add "rows" field to item_list. */
13452 13453 13454
      item_list.push_back(new Item_int((longlong) (ulonglong)
				       join->best_positions[i]. records_read,
				       21));
unknown's avatar
af  
unknown committed
13455
      /* Build "Extra" field and add it to item_list. */
unknown's avatar
unknown committed
13456
      my_bool key_read=table->key_read;
unknown's avatar
af  
unknown committed
13457 13458
      if ((tab->type == JT_NEXT || tab->type == JT_CONST) &&
          table->used_keys.is_set(tab->index))
unknown's avatar
unknown committed
13459
	key_read=1;
unknown's avatar
af  
unknown committed
13460 13461 13462 13463
      if (quick_type == QUICK_SELECT_I::QS_TYPE_ROR_INTERSECT &&
          !((QUICK_ROR_INTERSECT_SELECT*)tab->select->quick)->need_to_fetch_row)
        key_read=1;
        
unknown's avatar
unknown committed
13464
      if (tab->info)
unknown's avatar
unknown committed
13465
	item_list.push_back(new Item_string(tab->info,strlen(tab->info),cs));
13466
      else
unknown's avatar
unknown committed
13467
      {
unknown's avatar
af  
unknown committed
13468 13469 13470 13471 13472 13473 13474
        if (quick_type == QUICK_SELECT_I::QS_TYPE_ROR_UNION || 
            quick_type == QUICK_SELECT_I::QS_TYPE_ROR_INTERSECT ||
            quick_type == QUICK_SELECT_I::QS_TYPE_INDEX_MERGE)
        {
          extra.append("; Using ");
          tab->select->quick->add_info_string(&extra);
        }
13475
	if (tab->select)
unknown's avatar
unknown committed
13476
	{
13477 13478
	  if (tab->use_quick == 2)
	  {
13479
            char buf[MAX_KEY/8+1];
unknown's avatar
af  
unknown committed
13480 13481 13482
            extra.append("; Range checked for each record (index map: 0x");
            extra.append(tab->keys.print(buf));
            extra.append(')');
13483
	  }
13484
	  else if (tab->select->cond)
13485 13486 13487 13488 13489 13490 13491 13492 13493 13494 13495 13496 13497 13498 13499
          {
            const COND *pushed_cond= tab->table->file->pushed_cond;

            if (thd->variables.engine_condition_pushdown && pushed_cond)
            {
              extra.append("; Using where with pushed condition");
              if (thd->lex->describe & DESCRIBE_EXTENDED)
              {
                extra.append(": ");
                ((COND *)pushed_cond)->print(&extra);
              }
            }
            else
              extra.append("; Using where");
          }
unknown's avatar
unknown committed
13500
	}
13501
	if (key_read)
13502 13503 13504 13505 13506 13507
        {
          if (quick_type == QUICK_SELECT_I::QS_TYPE_GROUP_MIN_MAX)
            extra.append("; Using index for group-by");
          else
            extra.append("; Using index");
        }
13508
	if (table->reginfo.not_exists_optimize)
unknown's avatar
af  
unknown committed
13509
	  extra.append("; Not exists");
13510 13511 13512
	if (need_tmp_table)
	{
	  need_tmp_table=0;
unknown's avatar
af  
unknown committed
13513
	  extra.append("; Using temporary");
13514 13515 13516 13517
	}
	if (need_order)
	{
	  need_order=0;
unknown's avatar
af  
unknown committed
13518
	  extra.append("; Using filesort");
13519
	}
13520
	if (distinct & test_all_bits(used_tables,thd->used_tables))
unknown's avatar
af  
unknown committed
13521 13522 13523 13524 13525 13526 13527 13528 13529 13530 13531
	  extra.append("; Distinct");
        
        /* Skip initial "; "*/
        const char *str= extra.ptr();
        uint32 len= extra.length();
        if (len)
        {
          str += 2;
          len -= 2;
        }
	item_list.push_back(new Item_string(str, len, cs));
unknown's avatar
unknown committed
13532 13533 13534
      }
      // For next iteration
      used_tables|=table->map;
13535
      if (result->send_data(item_list))
13536
	join->error= 1;
unknown's avatar
unknown committed
13537
    }
unknown's avatar
unknown committed
13538
  }
unknown's avatar
unknown committed
13539 13540 13541 13542 13543 13544 13545
  for (SELECT_LEX_UNIT *unit= join->select_lex->first_inner_unit();
       unit;
       unit= unit->next_unit())
  {
    if (mysql_explain_union(thd, unit, result))
      DBUG_VOID_RETURN;
  }
unknown's avatar
unknown committed
13546 13547 13548
  DBUG_VOID_RETURN;
}

13549

unknown's avatar
unknown committed
13550
bool mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit, select_result *result)
unknown's avatar
unknown committed
13551
{
unknown's avatar
unknown committed
13552
  DBUG_ENTER("mysql_explain_union");
unknown's avatar
unknown committed
13553
  bool res= 0;
unknown's avatar
unknown committed
13554
  SELECT_LEX *first= unit->first_select();
unknown's avatar
af  
unknown committed
13555

unknown's avatar
unknown committed
13556 13557 13558 13559
  for (SELECT_LEX *sl= first;
       sl;
       sl= sl->next_select())
  {
unknown's avatar
af  
unknown committed
13560 13561 13562 13563 13564 13565 13566 13567 13568 13569 13570 13571 13572 13573 13574 13575 13576 13577 13578 13579 13580 13581 13582
    // drop UNCACHEABLE_EXPLAIN, because it is for internal usage only
    uint8 uncacheable= (sl->uncacheable & ~UNCACHEABLE_EXPLAIN);
    sl->type= (((&thd->lex->select_lex)==sl)?
	       ((thd->lex->all_selects_list != sl) ? 
		primary_key_name : "SIMPLE"):
	       ((sl == first)?
		((sl->linkage == DERIVED_TABLE_TYPE) ?
		 "DERIVED":
		 ((uncacheable & UNCACHEABLE_DEPENDENT) ?
		  "DEPENDENT SUBQUERY":
		  (uncacheable?"UNCACHEABLE SUBQUERY":
		   "SUBQUERY"))):
		((uncacheable & UNCACHEABLE_DEPENDENT) ?
		 "DEPENDENT UNION":
		 uncacheable?"UNCACHEABLE UNION":
		 "UNION")));
    sl->options|= SELECT_DESCRIBE;
  }
  if (first->next_select())
  {
    unit->fake_select_lex->select_number= UINT_MAX; // jost for initialization
    unit->fake_select_lex->type= "UNION RESULT";
    unit->fake_select_lex->options|= SELECT_DESCRIBE;
13583 13584
    if (!(res= unit->prepare(thd, result, SELECT_NO_UNLOCK | SELECT_DESCRIBE,
                             "")))
unknown's avatar
af  
unknown committed
13585 13586 13587 13588 13589 13590
      res= unit->exec();
    res|= unit->cleanup();
  }
  else
  {
    thd->lex->current_select= first;
13591
    unit->set_limit(unit->global_parameters);
unknown's avatar
af  
unknown committed
13592 13593 13594 13595 13596 13597 13598 13599 13600 13601 13602 13603
    res= mysql_select(thd, &first->ref_pointer_array,
			(TABLE_LIST*) first->table_list.first,
			first->with_wild, first->item_list,
			first->where,
			first->order_list.elements +
			first->group_list.elements,
			(ORDER*) first->order_list.first,
			(ORDER*) first->group_list.first,
			first->having,
			(ORDER*) thd->lex->proc_list.first,
			first->options | thd->options | SELECT_DESCRIBE,
			result, unit, first);
unknown's avatar
unknown committed
13604
  }
unknown's avatar
unknown committed
13605
  DBUG_RETURN(res || thd->net.report_error);
unknown's avatar
unknown committed
13606 13607
}

13608

13609 13610 13611 13612 13613 13614
/*
  Print joins from the FROM clause

  SYNOPSIS
    print_join()
    thd     thread handler
13615
    str     string where table should be printed
13616 13617 13618 13619 13620 13621 13622 13623 13624 13625 13626 13627 13628 13629 13630 13631
    tables  list of tables in join
*/

static void print_join(THD *thd, String *str, List<TABLE_LIST> *tables)
{
  /* List is reversed => we should reverse it before using */
  List_iterator_fast<TABLE_LIST> ti(*tables);
  TABLE_LIST **table= (TABLE_LIST **)thd->alloc(sizeof(TABLE_LIST*) *
                                                tables->elements);
  if (table == 0)
    return;  // out of memory

  for (TABLE_LIST **t= table + (tables->elements - 1); t >= table; t--)
    *t= ti++;

  DBUG_ASSERT(tables->elements >= 1);
unknown's avatar
unknown committed
13632
  (*table)->print(thd, str);
13633 13634

  TABLE_LIST **end= table + tables->elements;
unknown's avatar
unknown committed
13635
  for (TABLE_LIST **tbl= table + 1; tbl < end; tbl++)
13636 13637
  {
    TABLE_LIST *curr= *tbl;
unknown's avatar
unknown committed
13638
    if (curr->outer_join)
unknown's avatar
unknown committed
13639
      str->append(" left join ", 11); // MySQL converts right to left joins
13640 13641 13642 13643 13644 13645 13646 13647 13648 13649 13650 13651 13652 13653 13654 13655 13656 13657 13658 13659 13660 13661 13662 13663 13664 13665 13666 13667 13668 13669 13670
    else if (curr->straight)
      str->append(" straight_join ", 15);
    else
      str->append(" join ", 6);
    curr->print(thd, str);
    if (curr->on_expr)
    {
      str->append(" on(", 4);
      curr->on_expr->print(str);
      str->append(')');
    }
  }
}


/*
  Print table as it should be in join list

  SYNOPSIS
    st_table_list::print();
    str   string where table should bbe printed
*/

void st_table_list::print(THD *thd, String *str)
{
  if (nested_join)
  {
    str->append('(');
    print_join(thd, str, &nested_join->join_list);
    str->append(')');
  }
13671
  else
unknown's avatar
VIEW  
unknown committed
13672
  {
13673 13674
    const char *cmp_name;                         // Name to compare with alias
    if (view_name.str)
unknown's avatar
VIEW  
unknown committed
13675
    {
13676 13677 13678 13679
      append_identifier(thd, str, view_db.str, view_db.length);
      str->append('.');
      append_identifier(thd, str, view_name.str, view_name.length);
      cmp_name= view_name.str;
unknown's avatar
VIEW  
unknown committed
13680
    }
13681 13682 13683 13684 13685 13686 13687 13688 13689 13690 13691
    else if (derived)
    {
      str->append('(');
      derived->print(str);
      str->append(')');
      cmp_name= "";                               // Force printing of alias
    }
    else
    {
      append_identifier(thd, str, db, db_length);
      str->append('.');
13692 13693
      if (schema_table)
      {
unknown's avatar
unknown committed
13694 13695 13696
        append_identifier(thd, str, schema_table_name,
                          strlen(schema_table_name));
        cmp_name= schema_table_name;
13697 13698 13699
      }
      else
      {
13700 13701
        append_identifier(thd, str, table_name, table_name_length);
        cmp_name= table_name;
13702
      }
13703 13704
    }
    if (my_strcasecmp(table_alias_charset, cmp_name, alias))
13705 13706
    {
      str->append(' ');
13707
      append_identifier(thd, str, alias, strlen(alias));
13708 13709 13710 13711
    }
  }
}

13712

unknown's avatar
unknown committed
13713 13714
void st_select_lex::print(THD *thd, String *str)
{
unknown's avatar
unknown committed
13715
  /* QQ: thd may not be set for sub queries, but this should be fixed */
unknown's avatar
unknown committed
13716 13717 13718
  if (!thd)
    thd= current_thd;

13719
  str->append("select ", 7);
13720

13721
  /* First add options */
unknown's avatar
unknown committed
13722
  if (options & SELECT_STRAIGHT_JOIN)
13723
    str->append("straight_join ", 14);
unknown's avatar
af  
unknown committed
13724
  if ((thd->lex->lock_option == TL_READ_HIGH_PRIORITY) &&
unknown's avatar
unknown committed
13725
      (this == &thd->lex->select_lex))
13726
    str->append("high_priority ", 14);
unknown's avatar
unknown committed
13727
  if (options & SELECT_DISTINCT)
13728
    str->append("distinct ", 9);
unknown's avatar
unknown committed
13729
  if (options & SELECT_SMALL_RESULT)
unknown's avatar
af  
unknown committed
13730
    str->append("sql_small_result ", 17);
unknown's avatar
unknown committed
13731
  if (options & SELECT_BIG_RESULT)
unknown's avatar
af  
unknown committed
13732
    str->append("sql_big_result ", 15);
unknown's avatar
unknown committed
13733
  if (options & OPTION_BUFFER_RESULT)
unknown's avatar
af  
unknown committed
13734
    str->append("sql_buffer_result ", 18);
unknown's avatar
unknown committed
13735
  if (options & OPTION_FOUND_ROWS)
unknown's avatar
af  
unknown committed
13736
    str->append("sql_calc_found_rows ", 20);
unknown's avatar
unknown committed
13737
  if (!thd->lex->safe_to_cache_query)
unknown's avatar
af  
unknown committed
13738
    str->append("sql_no_cache ", 13);
unknown's avatar
unknown committed
13739
  if (options & OPTION_TO_QUERY_CACHE)
unknown's avatar
af  
unknown committed
13740
    str->append("sql_cache ", 10);
unknown's avatar
unknown committed
13741 13742 13743 13744 13745 13746 13747 13748 13749 13750 13751 13752 13753 13754 13755 13756 13757 13758 13759 13760

  //Item List
  bool first= 1;
  List_iterator_fast<Item> it(item_list);
  Item *item;
  while ((item= it++))
  {
    if (first)
      first= 0;
    else
      str->append(',');
    item->print_item_w_name(str);
  }

  /*
    from clause
    TODO: support USING/FORCE/IGNORE index
  */
  if (table_list.elements)
  {
13761
    str->append(" from ", 6);
13762 13763
    /* go through join tree */
    print_join(thd, str, &top_join_list);
unknown's avatar
unknown committed
13764 13765
  }

13766 13767
  // Where
  Item *cur_where= where;
unknown's avatar
unknown committed
13768
  if (join)
13769 13770
    cur_where= join->conds;
  if (cur_where)
unknown's avatar
unknown committed
13771
  {
13772
    str->append(" where ", 7);
13773
    cur_where->print(str);
unknown's avatar
unknown committed
13774 13775
  }

13776
  // group by & olap
unknown's avatar
unknown committed
13777 13778
  if (group_list.elements)
  {
13779
    str->append(" group by ", 10);
unknown's avatar
unknown committed
13780 13781 13782 13783
    print_order(str, (ORDER *) group_list.first);
    switch (olap)
    {
      case CUBE_TYPE:
13784
	str->append(" with cube", 10);
unknown's avatar
unknown committed
13785 13786
	break;
      case ROLLUP_TYPE:
13787
	str->append(" with rollup", 12);
unknown's avatar
unknown committed
13788 13789 13790 13791 13792 13793
	break;
      default:
	;  //satisfy compiler
    }
  }

13794 13795
  // having
  Item *cur_having= having;
unknown's avatar
unknown committed
13796
  if (join)
13797
    cur_having= join->having;
unknown's avatar
unknown committed
13798

13799
  if (cur_having)
unknown's avatar
unknown committed
13800
  {
13801
    str->append(" having ", 8);
13802
    cur_having->print(str);
unknown's avatar
unknown committed
13803 13804 13805 13806
  }

  if (order_list.elements)
  {
13807
    str->append(" order by ", 10);
unknown's avatar
unknown committed
13808 13809 13810 13811 13812 13813 13814 13815
    print_order(str, (ORDER *) order_list.first);
  }

  // limit
  print_limit(thd, str);

  // PROCEDURE unsupported here
}
unknown's avatar
af  
unknown committed
13816 13817 13818 13819 13820 13821 13822 13823 13824 13825


/*
  change select_result object of JOIN

  SYNOPSIS
    JOIN::change_result()
    res		new select_result object

  RETURN
unknown's avatar
unknown committed
13826 13827
    FALSE - OK
    TRUE  - error
unknown's avatar
af  
unknown committed
13828 13829
*/

unknown's avatar
unknown committed
13830
bool JOIN::change_result(select_result *res)
unknown's avatar
af  
unknown committed
13831 13832 13833
{
  DBUG_ENTER("JOIN::change_result");
  result= res;
13834 13835
  if (!procedure && (result->prepare(fields_list, select_lex->master_unit()) ||
                     result->prepare2()))
unknown's avatar
af  
unknown committed
13836
  {
unknown's avatar
unknown committed
13837
    DBUG_RETURN(TRUE);
unknown's avatar
af  
unknown committed
13838
  }
unknown's avatar
unknown committed
13839
  DBUG_RETURN(FALSE);
unknown's avatar
af  
unknown committed
13840
}