sql_select.h 84.5 KB
Newer Older
1 2 3
#ifndef SQL_SELECT_INCLUDED
#define SQL_SELECT_INCLUDED

4
/* Copyright (c) 2000, 2013, Oracle and/or its affiliates.
5
   Copyright (c) 2008, 2020, MariaDB Corporation.
unknown's avatar
unknown committed
6

unknown's avatar
unknown committed
7 8
   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
unknown's avatar
unknown committed
9
   the Free Software Foundation; version 2 of the License.
unknown's avatar
unknown committed
10

unknown's avatar
unknown committed
11 12 13 14
   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.
unknown's avatar
unknown committed
15

unknown's avatar
unknown committed
16 17
   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
Vicențiu Ciorbaru's avatar
Vicențiu Ciorbaru committed
18
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335  USA */
unknown's avatar
unknown committed
19

unknown's avatar
unknown committed
20 21 22 23 24 25
/**
  @file

  @brief
  classes to use when handling where clause
*/
unknown's avatar
unknown committed
26

27
#ifdef USE_PRAGMA_INTERFACE
unknown's avatar
unknown committed
28 29 30 31
#pragma interface			/* gcc class implementation */
#endif

#include "procedure.h"
32 33 34
#include "sql_array.h"                        /* Array */
#include "records.h"                          /* READ_RECORD */
#include "opt_range.h"                /* SQL_SELECT, QUICK_SELECT_I */
35
#include "filesort.h"
36

37
typedef struct st_join_table JOIN_TAB;
38
/* Values in optimize */
39 40 41
#define KEY_OPTIMIZE_EXISTS		1U
#define KEY_OPTIMIZE_REF_OR_NULL	2U
#define KEY_OPTIMIZE_EQ	                4U
42 43 44 45

inline uint get_hash_join_key_no() { return MAX_KEY; }

inline bool is_hash_join_key_no(uint key) { return key == MAX_KEY; }
46

unknown's avatar
unknown committed
47 48
typedef struct keyuse_t {
  TABLE *table;
unknown's avatar
unknown committed
49
  Item	*val;				/**< or value if no field */
unknown's avatar
unknown committed
50
  table_map used_tables;
51
  uint	key, keypart, optimize;
unknown's avatar
unknown committed
52 53
  key_part_map keypart_map;
  ha_rows      ref_table_rows;
unknown's avatar
unknown committed
54
  /**
55 56 57 58
    If true, the comparison this value was created from will not be
    satisfied if val has NULL 'value'.
  */
  bool null_rejecting;
59 60 61 62 63 64 65 66 67 68 69
  /*
    !NULL - This KEYUSE was created from an equality that was wrapped into
            an Item_func_trig_cond. This means the equality (and validity of 
            this KEYUSE element) can be turned on and off. The on/off state 
            is indicted by the pointed value:
              *cond_guard == TRUE <=> equality condition is on
              *cond_guard == FALSE <=> equality condition is off

    NULL  - Otherwise (the source equality can't be turned off)
  */
  bool *cond_guard;
70 71 72 73 74
  /*
     0..64    <=> This was created from semi-join IN-equality # sj_pred_no.
     MAX_UINT  Otherwise
  */
  uint         sj_pred_no;
75

76 77 78 79 80 81
  /*
    If this is NULL than KEYUSE is always enabled.
    Otherwise it points to the enabling flag for this keyuse (true <=> enabled)
  */
  bool *validity_ref;

82
  bool is_for_hash_join() { return is_hash_join_key_no(key); }
unknown's avatar
unknown committed
83 84
} KEYUSE;

85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114

struct KEYUSE_EXT: public KEYUSE
{
  /*
    This keyuse can be used only when the partial join being extended
    contains the tables from this table map
  */
  table_map needed_in_prefix;
  /* The enabling flag for keyuses usable for splitting */
  bool validity_var;
};

/// Used when finding key fields
struct KEY_FIELD {
  Field		*field;
  Item_bool_func *cond;
  Item		*val;			///< May be empty if diff constant
  uint		level;
  uint		optimize;
  bool		eq_func;
  /**
    If true, the condition this struct represents will not be satisfied
    when val IS NULL.
  */
  bool          null_rejecting;
  bool         *cond_guard; /* See KEYUSE::cond_guard */
  uint          sj_pred_no; /* See KEYUSE::sj_pred_no */
};


Igor Babaev's avatar
Igor Babaev committed
115 116
#define NO_KEYPART ((uint)(-1))

unknown's avatar
unknown committed
117 118
class store_key;

119 120
const int NO_REF_PART= uint(-1);

unknown's avatar
unknown committed
121 122 123
typedef struct st_table_ref
{
  bool		key_err;
Konstantin Osipov's avatar
Konstantin Osipov committed
124 125
  /** True if something was read into buffer in join_read_key.  */
  bool          has_record;
unknown's avatar
unknown committed
126 127 128 129 130
  uint          key_parts;                ///< num of ...
  uint          key_length;               ///< length of key_buff
  int           key;                      ///< key no
  uchar         *key_buff;                ///< value to look for with key
  uchar         *key_buff2;               ///< key_buff+key_length
unknown's avatar
unknown committed
131
  store_key     **key_copy;               //
132 133 134 135 136 137 138

  /*
    Bitmap of key parts which refer to constants. key_copy only has copiers for
    non-const key parts.
  */
  key_part_map  const_ref_part_map;

unknown's avatar
unknown committed
139
  Item          **items;                  ///< val()'s for each keypart
140 141 142 143 144 145 146 147 148 149 150 151
  /*  
    Array of pointers to trigger variables. Some/all of the pointers may be
    NULL.  The ref access can be used iff
    
      for each used key part i, (!cond_guards[i] || *cond_guards[i]) 

    This array is used by subquery code. The subquery code may inject
    triggered conditions, i.e. conditions that can be 'switched off'. A ref 
    access created from such condition is not valid when at least one of the 
    underlying conditions is switched off (see subquery code for more details)
  */
  bool          **cond_guards;
unknown's avatar
unknown committed
152
  /**
153 154 155 156
    (null_rejecting & (1<<i)) means the condition is '=' and no matching
    rows will be produced if items[i] IS NULL (see add_not_null_conds())
  */
  key_part_map  null_rejecting;
unknown's avatar
unknown committed
157
  table_map	depend_map;		  ///< Table depends on these tables.
158

159
  /* null byte position in the key_buf. Used for REF_OR_NULL optimization */
160
  uchar          *null_ref_key;
161
  /* 
162 163 164
    ref_or_null optimization: number of key part that alternates between
    the lookup value or NULL (there's only one such part). 
    If we're not using ref_or_null, the value is NO_REF_PART
165 166 167
  */
  uint           null_ref_part;

Konstantin Osipov's avatar
Konstantin Osipov committed
168 169 170 171 172
  /*
    The number of times the record associated with this key was used
    in the join.
  */
  ha_rows       use_count;
unknown's avatar
unknown committed
173

174 175 176
  /*
    TRUE <=> disable the "cache" as doing lookup with the same key value may
    produce different results (because of Index Condition Pushdown)
unknown's avatar
unknown committed
177

178 179
  */
  bool          disable_cache;
unknown's avatar
unknown committed
180

181 182 183 184 185 186
  /*
    If true, this ref access was constructed from equalities generated by
    LATERAL DERIVED (aka GROUP BY splitting) optimization
  */
  bool          uses_splitting;

unknown's avatar
unknown committed
187
  bool tmp_table_index_lookup_init(THD *thd, KEY *tmp_key, Item_iterator &it,
unknown's avatar
unknown committed
188
                                   bool value, uint skip= 0);
189
  bool is_access_triggered();
unknown's avatar
unknown committed
190 191 192 193
} TABLE_REF;


/*
194
  The structs which holds the join connections and join states
unknown's avatar
unknown committed
195 196
*/
enum join_type { JT_UNKNOWN,JT_SYSTEM,JT_CONST,JT_EQ_REF,JT_REF,JT_MAYBE_REF,
197
		 JT_ALL, JT_RANGE, JT_NEXT, JT_FT, JT_REF_OR_NULL,
198
		 JT_UNIQUE_SUBQUERY, JT_INDEX_SUBQUERY, JT_INDEX_MERGE,
199
                 JT_HASH, JT_HASH_RANGE, JT_HASH_NEXT, JT_HASH_INDEX_MERGE};
unknown's avatar
unknown committed
200 201 202

class JOIN;

203 204 205 206 207 208 209
enum enum_nested_loop_state
{
  NESTED_LOOP_KILLED= -2, NESTED_LOOP_ERROR= -1,
  NESTED_LOOP_OK= 0, NESTED_LOOP_NO_MORE_ROWS= 1,
  NESTED_LOOP_QUERY_LIMIT= 3, NESTED_LOOP_CURSOR_LIMIT= 4
};

210

211 212 213 214 215 216 217 218 219 220 221
/* Possible sj_strategy values */
enum sj_strategy_enum
{
  SJ_OPT_NONE=0,
  SJ_OPT_DUPS_WEEDOUT=1,
  SJ_OPT_LOOSE_SCAN  =2,
  SJ_OPT_FIRST_MATCH =3,
  SJ_OPT_MATERIALIZE =4,
  SJ_OPT_MATERIALIZE_SCAN=5
};

222
/* Values for JOIN_TAB::packed_info */
223 224 225 226
#define TAB_INFO_HAVE_VALUE 1U
#define TAB_INFO_USING_INDEX 2U
#define TAB_INFO_USING_WHERE 4U
#define TAB_INFO_FULL_SCAN_ON_NULL 8U
227

228 229
typedef enum_nested_loop_state
(*Next_select_func)(JOIN *, struct st_join_table *, bool);
230
Next_select_func setup_end_select_func(JOIN *join, JOIN_TAB *tab);
231
int rr_sequential(READ_RECORD *info);
232
int read_record_func_for_rr_and_unpack(READ_RECORD *info);
233
Item *remove_pushed_top_conjuncts(THD *thd, Item *cond);
234 235 236
Item *and_new_conditions_to_optimized_cond(THD *thd, Item *cond,
                                           COND_EQUAL **cond_eq,
                                           List<Item> &new_conds,
237
                                           Item::cond_result *cond_value);
238

239
#include "sql_explain.h"
Sergey Petrunya's avatar
Sergey Petrunya committed
240 241 242 243 244

/**************************************************************************************
 * New EXPLAIN structures END
 *************************************************************************************/

245
class JOIN_CACHE;
246
class SJ_TMP_TABLE;
247
class JOIN_TAB_RANGE;
248 249
class AGGR_OP;
class Filesort;
250 251
struct SplM_plan_info;
class SplM_opt_info;
252

unknown's avatar
unknown committed
253 254
typedef struct st_join_table {
  TABLE		*table;
255
  TABLE_LIST    *tab_list;
256
  KEYUSE	*keyuse;       /**< pointer to first used key */
257
  KEY           *hj_key;       /**< descriptor of the used best hash join key
258
                                    not supported by any index               */
unknown's avatar
unknown committed
259 260
  SQL_SELECT	*select;
  COND		*select_cond;
261
  COND          *on_precond;    /**< part of on condition to check before
262
                                     accessing the first inner table         */
unknown's avatar
unknown committed
263
  QUICK_SELECT_I *quick;
264 265 266 267 268 269 270 271
  /* 
    The value of select_cond before we've attempted to do Index Condition
    Pushdown. We may need to restore everything back if we first choose one
    index but then reconsider (see test_if_skip_sort_order() for such
    scenarios).
    NULL means no index condition pushdown was performed.
  */
  Item          *pre_idx_push_select_cond;
272 273 274
  /*
    Pointer to the associated ON expression. on_expr_ref=!NULL except for
    degenerate joins. 
275 276 277 278 279 280

    Optimization phase: *on_expr_ref!=NULL for tables that are the single
      tables on the inner side of the outer join (t1 LEFT JOIN t2 ON...)

    Execution phase: *on_expr_ref!=NULL for tables that are first inner tables
      within an outer join (which may have multiple tables)
281 282
  */
  Item	       **on_expr_ref;
unknown's avatar
unknown committed
283 284 285 286 287 288 289
  COND_EQUAL    *cond_equal;    /**< multiple equalities for the on expression */
  st_join_table *first_inner;   /**< first inner table for including outerjoin */
  bool           found;         /**< true after all matches or null complement */
  bool           not_null_compl;/**< true before null complement is added      */
  st_join_table *last_inner;    /**< last table table for embedding outer join */
  st_join_table *first_upper;  /**< first inner table for embedding outer join */
  st_join_table *first_unmatched; /**< used for optimization purposes only     */
290 291

  /*
Sergey Petrunya's avatar
Sergey Petrunya committed
292
    For join tabs that are inside an SJM bush: root of the bush
293 294 295
  */
  st_join_table *bush_root_tab;

Sergey Petrunya's avatar
Sergey Petrunya committed
296
  /* TRUE <=> This join_tab is inside an SJM bush and is the last leaf tab here */
297 298 299 300 301 302 303
  bool          last_leaf_in_bush;
  
  /*
    ptr  - this is a bush, and ptr points to description of child join_tab
           range
    NULL - this join tab has no bush children
  */
304
  JOIN_TAB_RANGE *bush_children;
305 306
  
  /* Special content for EXPLAIN 'Extra' column or NULL if none */
307
  enum explain_extra_tag info;
Sergei Petrunia's avatar
Sergei Petrunia committed
308
  
Sergei Petrunia's avatar
Sergei Petrunia committed
309
  Table_access_tracker *tracker;
310

311
  Table_access_tracker *jbuf_tracker;
312 313 314 315 316 317
  /* 
    Bitmap of TAB_INFO_* bits that encodes special line for EXPLAIN 'Extra'
    column, or 0 if there is no info.
  */
  uint          packed_info;

318
  //  READ_RECORD::Setup_func materialize_table;
Konstantin Osipov's avatar
Konstantin Osipov committed
319
  READ_RECORD::Setup_func read_first_record;
320
  Next_select_func next_select;
unknown's avatar
unknown committed
321
  READ_RECORD	read_record;
322 323 324 325 326
  /* 
    Currently the following two fields are used only for a [NOT] IN subquery
    if it is executed by an alternative full table scan when the left operand of
    the subquery predicate is evaluated to NULL.
  */  
Konstantin Osipov's avatar
Konstantin Osipov committed
327 328
  READ_RECORD::Setup_func save_read_first_record;/* to save read_first_record */
  READ_RECORD::Read_func save_read_record;/* to save read_record.read_record */
unknown's avatar
unknown committed
329
  double	worst_seeks;
unknown's avatar
unknown committed
330 331
  key_map	const_keys;			/**< Keys with constant part */
  key_map	checked_keys;			/**< Keys checked in find_best */
unknown's avatar
unknown committed
332
  key_map	needed_reg;
unknown's avatar
unknown committed
333
  key_map       keys;                           /**< all keys with can be used */
334 335 336 337 338 339 340 341 342 343 344 345 346

  /* Either #rows in the table or 1 for const table.  */
  ha_rows	records;
  /*
    Number of records that will be scanned (yes scanned, not returned) by the
    best 'independent' access method, i.e. table scan or QUICK_*_SELECT)
  */
  ha_rows       found_records;
  /*
    Cost of accessing the table using "ALL" or range/index_merge access
    method (but not 'index' for some reason), i.e. this matches method which
    E(#records) is in found_records.
  */
347
  double        read_time;
348
  
349
  /* Copy of POSITION::records_read, set by get_best_combination() */
Igor Babaev's avatar
Igor Babaev committed
350
  double        records_read;
351
  
Igor Babaev's avatar
Igor Babaev committed
352 353
  /* The selectivity of the conditions that can be pushed to the table */ 
  double        cond_selectivity;  
Igor Babaev's avatar
Igor Babaev committed
354
  
355 356
  /* Startup cost for execution */
  double        startup_cost;
357 358 359
    
  double        partial_join_cardinality;

unknown's avatar
unknown committed
360
  table_map	dependent,key_dependent;
361 362 363 364 365 366 367 368 369 370
  /*
     1 - use quick select
     2 - use "Range checked for each record"
  */
  uint		use_quick;
  /*
    Index to use. Note: this is valid only for 'index' access, but not range or
    ref access.
  */
  uint          index;
unknown's avatar
unknown committed
371
  uint		status;				///< Save status for cache
372 373 374 375
  uint		used_fields;
  ulong         used_fieldlength;
  ulong         max_used_fieldlength;
  uint          used_blobs;
376 377
  uint          used_null_fields;
  uint          used_uneven_bit_fields;
unknown's avatar
unknown committed
378
  enum join_type type;
Igor Babaev's avatar
Igor Babaev committed
379 380 381
  bool          cached_eq_ref_table,eq_ref_table;
  bool          shortcut_for_distinct;
  bool          sorted;
unknown's avatar
unknown committed
382 383 384 385 386 387
  /* 
    If it's not 0 the number stored this field indicates that the index
    scan has been chosen to access the table data and we expect to scan 
    this number of rows for the table.
  */ 
  ha_rows       limit; 
unknown's avatar
unknown committed
388
  TABLE_REF	ref;
389 390 391 392 393 394 395
  /* TRUE <=> condition pushdown supports other tables presence */
  bool          icp_other_tables_ok;
  /* 
    TRUE <=> condition pushed to the index has to be factored out of
    the condition pushed to the table
  */
  bool          idx_cond_fact_out;
396
  bool          use_join_cache;
397
  uint          used_join_cache_level;
398
  ulong         join_buffer_size_limit;
399 400 401 402 403 404
  JOIN_CACHE	*cache;
  /*
    Index condition for BKA access join
  */
  Item          *cache_idx_cond;
  SQL_SELECT    *cache_select;
405
  AGGR_OP       *aggr;
406
  JOIN		*join;
407 408 409 410 411
  /*
    Embedding SJ-nest (may be not the direct parent), or NULL if none.
    This variable holds the result of table pullout.
  */
  TABLE_LIST    *emb_sj_nest;
Sergey Petrunya's avatar
Sergey Petrunya committed
412

413 414 415 416
  /* FirstMatch variables (final QEP) */
  struct st_join_table *first_sj_inner_tab;
  struct st_join_table *last_sj_inner_tab;

417 418 419
  /* Variables for semi-join duplicate elimination */
  SJ_TMP_TABLE  *flush_weedout_table;
  SJ_TMP_TABLE  *check_weed_out_table;
420 421
  /* for EXPLAIN only: */
  SJ_TMP_TABLE  *first_weedout_table;
422 423 424 425 426 427

  /**
    reference to saved plan and execution statistics
  */
  Explain_table_access *explain_plan;

428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443
  /*
    If set, means we should stop join enumeration after we've got the first
    match and return to the specified join tab. May point to
    join->join_tab[-1] which means stop join execution after the first
    match.
  */
  struct st_join_table  *do_firstmatch;
 
  /* 
     ptr  - We're doing a LooseScan, this join tab is the first (i.e. 
            "driving") join tab), and ptr points to the last join tab
            handled by the strategy. loosescan_match_tab->found_match
            should be checked to see if the current value group had a match.
     NULL - Not doing a loose scan on this join tab.
  */
  struct st_join_table *loosescan_match_tab;
444 445 446
  
  /* TRUE <=> we are inside LooseScan range */
  bool inside_loosescan_range;
447 448 449 450

  /* Buffer to save index tuple to be able to skip duplicates */
  uchar *loosescan_buf;
  
451 452 453 454 455 456
  /* 
    Index used by LooseScan (we store it here separately because ref access
    stores it in tab->ref.key, while range scan stores it in tab->index, etc)
  */
  uint loosescan_key;

457 458 459 460 461 462 463 464 465 466 467 468 469
  /* Length of key tuple (depends on #keyparts used) to store in the above */
  uint loosescan_key_len;

  /* Used by LooseScan. TRUE<=> there has been a matching record combination */
  bool found_match;
  
  /*
    Used by DuplicateElimination. tab->table->ref must have the rowid
    whenever we have a current record.
  */
  int  keep_current_rowid;

  /* NestedOuterJoins: Bitmap of nested joins this table is part of */
470
  nested_join_map embedding_map;
unknown's avatar
unknown committed
471

472 473 474 475 476 477 478 479 480 481 482 483 484 485
  /* Tmp table info */
  TMP_TABLE_PARAM *tmp_table_param;

  /* Sorting related info */
  Filesort *filesort;
  SORT_INFO *filesort_result;
  
  /*
    Non-NULL value means this join_tab must do window function computation
    before reading.
  */
  Window_funcs_computation* window_funcs_step;

  /**
486
    List of topmost expressions in the select list. The *next* JOIN_TAB
487 488 489 490 491
    in the plan should use it to obtain correct values. Same applicable to
    all_fields. These lists are needed because after tmp tables functions
    will be turned to fields. These variables are pointing to
    tmp_fields_list[123]. Valid only for tmp tables and the last non-tmp
    table in the query plan.
Sergei Petrunia's avatar
Sergei Petrunia committed
492
    @see JOIN::make_aggr_tables_info()
493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511
  */
  List<Item> *fields;
  /** List of all expressions in the select list */
  List<Item> *all_fields;
  /*
    Pointer to the ref array slice which to switch to before sending
    records. Valid only for tmp tables.
  */
  Ref_ptr_array *ref_array;

  /** Number of records saved in tmp table */
  ha_rows send_records;

  /** HAVING condition for checking prior saving a record into tmp table*/
  Item *having;

  /** TRUE <=> remove duplicates on this table. */
  bool distinct;

512 513 514
  /*
    Semi-join strategy to be used for this join table. This is a copy of
    POSITION::sj_strategy field. This field is set up by the
515
    fix_semijoin_strategies_for_picked_join_order.
516
  */
517
  enum sj_strategy_enum sj_strategy;
518

Sergey Petrunya's avatar
Sergey Petrunya committed
519
  uint n_sj_tables;
520

521
  bool preread_init_done;
522 523 524 525 526 527 528 529 530 531 532 533

  /*
    Cost info to the range filter used when joining this join table
    (Defined when the best join order has been already chosen)
  */
  Range_rowid_filter_cost_info *range_rowid_filter_info;
  /* Rowid filter to be used when joining this join table */
  Rowid_filter *rowid_filter;
  /* Becomes true just after the used range filter has been built / filled */
  bool is_rowid_filter_built;

  void build_range_rowid_filter_if_needed();
534

535
  void cleanup();
536 537
  inline bool is_using_loose_index_scan()
  {
538 539 540
    const SQL_SELECT *sel= filesort ? filesort->select : select;
    return (sel && sel->quick &&
            (sel->quick->get_type() == QUICK_SELECT_I::QS_TYPE_GROUP_MIN_MAX));
541
  }
542 543 544 545 546
  bool is_using_agg_loose_index_scan ()
  {
    return (is_using_loose_index_scan() &&
            ((QUICK_GROUP_MIN_MAX_SELECT *)select->quick)->is_agg_distinct());
  }
547 548 549 550
  bool is_inner_table_of_semi_join_with_first_match()
  {
    return first_sj_inner_tab != NULL;
  }
Igor Babaev's avatar
Igor Babaev committed
551 552 553 554
  bool is_inner_table_of_semijoin()
  {
    return emb_sj_nest != NULL;
  }
555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576
  bool is_inner_table_of_outer_join()
  {
    return first_inner != NULL;
  }
  bool is_single_inner_of_semi_join_with_first_match()
  {
    return first_sj_inner_tab == this && last_sj_inner_tab == this;            
  }
  bool is_single_inner_of_outer_join()
  {
    return first_inner == this && first_inner->last_inner == this;
  }
  bool is_first_inner_for_outer_join()
  {
    return first_inner && first_inner == this;
  }
  bool use_match_flag()
  {
    return is_first_inner_for_outer_join() || first_sj_inner_tab == this ; 
  }
  bool check_only_first_match()
  {
577 578
    return is_inner_table_of_semi_join_with_first_match() ||
           (is_inner_table_of_outer_join() &&
579 580 581 582 583 584 585
            table->reginfo.not_exists_optimize);
  }
  bool is_last_inner_table()
  {
    return (first_inner && first_inner->last_inner == this) ||
           last_sj_inner_tab == this;
  }
Igor Babaev's avatar
Igor Babaev committed
586 587 588 589 590 591 592 593 594 595 596 597 598
  /*
    Check whether the table belongs to a nest of inner tables of an
    outer join or to a nest of inner tables of a semi-join
  */
  bool is_nested_inner()
  {
    if (first_inner && 
        (first_inner != first_inner->last_inner || first_inner->first_upper))
      return TRUE;
    if (first_sj_inner_tab && first_sj_inner_tab != last_sj_inner_tab)
      return TRUE;
    return FALSE;
  }
599 600 601 602 603 604
  struct st_join_table *get_first_inner_table()
  {
    if (first_inner)
      return first_inner;
    return first_sj_inner_tab; 
  }
605 606 607 608 609 610 611 612 613 614 615 616 617 618
  void set_select_cond(COND *to, uint line)
  {
    DBUG_PRINT("info", ("select_cond changes %p -> %p at line %u tab %p",
                        select_cond, to, line, this));
    select_cond= to;
  }
  COND *set_cond(COND *new_cond)
  {
    COND *tmp_select_cond= select_cond;
    set_select_cond(new_cond, __LINE__);
    if (select)
      select->cond= new_cond;
    return tmp_select_cond;
  }
619 620
  void calc_used_field_length(bool max_fl);
  ulong get_used_fieldlength()
621
  {
622 623 624
    if (!used_fieldlength)
      calc_used_field_length(FALSE);
    return used_fieldlength;
625
  }
626
  ulong get_max_used_fieldlength()
627
  {
628 629 630
    if (!max_used_fieldlength)
      calc_used_field_length(TRUE);
    return max_used_fieldlength;
631
  }
632
  double get_partial_join_cardinality() { return partial_join_cardinality; }
Igor Babaev's avatar
Igor Babaev committed
633
  bool hash_join_is_possible();
634
  int make_scan_filter();
635 636
  bool is_ref_for_hash_join() { return is_hash_join_key_no(ref.key); }
  KEY *get_keyinfo_by_key_no(uint key) 
637
  {
638
    return (is_hash_join_key_no(key) ? hj_key : table->key_info+key);
639
  }
640
  double scan_time();
unknown's avatar
unknown committed
641
  ha_rows get_examined_rows();
642
  bool preread_init();
643

644 645
  bool pfs_batch_update(JOIN *join);

646
  bool is_sjm_nest() { return MY_TEST(bush_children); }
647 648 649 650 651 652 653 654 655 656 657 658 659 660 661
  
  /*
    If this join_tab reads a non-merged semi-join (also called jtbm), return
    the select's number.  Otherwise, return 0.
  */
  int get_non_merged_semijoin_select() const
  {
    Item_in_subselect *subq;
    if (table->pos_in_table_list && 
        (subq= table->pos_in_table_list->jtbm_subselect))
    {
      return subq->unit->first_select()->select_number;
    }
    return 0; /* Not a merged semi-join */
  }
Igor Babaev's avatar
Igor Babaev committed
662 663 664 665 666 667 668 669 670 671

  bool access_from_tables_is_allowed(table_map used_tables,
                                     table_map sjm_lookup_tables)
  {
    table_map used_sjm_lookup_tables= used_tables & sjm_lookup_tables;
    return !used_sjm_lookup_tables ||
           (emb_sj_nest && 
            !(used_sjm_lookup_tables & ~emb_sj_nest->sj_inner_tables));
  }

Igor Babaev's avatar
Igor Babaev committed
672 673
  bool keyuse_is_valid_for_access_in_chosen_plan(JOIN *join, KEYUSE *keyuse);

674
  void remove_redundant_bnl_scan_conds();
675

676
  bool save_explain_data(Explain_table_access *eta, table_map prefix_tables,
677 678
                         bool distinct, struct st_join_table *first_top_tab);

679 680 681
  bool use_order() const; ///< Use ordering provided by chosen index?
  bool sort_table();
  bool remove_duplicates();
Marko Mäkelä's avatar
Marko Mäkelä committed
682

683
  void partial_cleanup();
684 685 686
  void add_keyuses_for_splitting();
  SplM_plan_info *choose_best_splitting(double record_count,
                                        table_map remaining_tables);
687 688
  bool fix_splitting(SplM_plan_info *spl_plan, table_map remaining_tables,
                     bool is_const_table);
unknown's avatar
unknown committed
689
} JOIN_TAB;
690 691


692
#include "sql_join_cache.h"
693

694 695 696 697 698 699 700
enum_nested_loop_state
sub_select_cache(JOIN *join, JOIN_TAB *join_tab, bool end_of_records);
enum_nested_loop_state 
sub_select(JOIN *join, JOIN_TAB *join_tab, bool end_of_records);
enum_nested_loop_state
sub_select_postjoin_aggr(JOIN *join, JOIN_TAB *join_tab, bool end_of_records);

701 702 703 704 705 706 707
enum_nested_loop_state
end_send_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
	       bool end_of_records);
enum_nested_loop_state
end_write_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
		bool end_of_records);

708

709 710 711 712 713 714 715 716 717 718
class Semi_join_strategy_picker
{
public:
  /* Called when starting to build a new join prefix */
  virtual void set_empty() = 0;

  /* 
    Update internal state after another table has been added to the join
    prefix
  */
Monty's avatar
Monty committed
719
  virtual void set_from_prev(POSITION *prev) = 0;
720 721 722 723 724 725 726 727 728
  
  virtual bool check_qep(JOIN *join,
                         uint idx,
                         table_map remaining_tables, 
                         const JOIN_TAB *new_join_tab,
                         double *record_count,
                         double *read_time,
                         table_map *handled_fanout,
                         sj_strategy_enum *strategy,
Monty's avatar
Monty committed
729
                         POSITION *loose_scan_pos) = 0;
730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759

  virtual void mark_used() = 0;

  virtual ~Semi_join_strategy_picker() {} 
};


/*
  Duplicate Weedout strategy optimization state
*/

class Duplicate_weedout_picker : public Semi_join_strategy_picker
{
  /* The first table that the strategy will need to handle */
  uint  first_dupsweedout_table;

  /*
    Tables that we will need to have in the prefix to do the weedout step
    (all inner and all outer that the involved semi-joins are correlated with)
  */
  table_map dupsweedout_tables;
  
  bool is_used;
public:
  void set_empty()
  {
    dupsweedout_tables= 0;
    first_dupsweedout_table= MAX_TABLES;
    is_used= FALSE;
  }
Monty's avatar
Monty committed
760
  void set_from_prev(POSITION *prev);
761 762 763 764 765 766 767 768 769
  
  bool check_qep(JOIN *join,
                 uint idx,
                 table_map remaining_tables, 
                 const JOIN_TAB *new_join_tab,
                 double *record_count,
                 double *read_time,
                 table_map *handled_fanout,
                 sj_strategy_enum *stratey,
Monty's avatar
Monty committed
770
                 POSITION *loose_scan_pos);
771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805

  void mark_used() { is_used= TRUE; }
  friend void fix_semijoin_strategies_for_picked_join_order(JOIN *join);
};


class Firstmatch_picker : public Semi_join_strategy_picker
{
  /*
    Index of the first inner table that we intend to handle with this
    strategy
  */
  uint first_firstmatch_table;
  /*
    Tables that were not in the join prefix when we've started considering 
    FirstMatch strategy.
  */
  table_map first_firstmatch_rtbl;
  /* 
    Tables that need to be in the prefix before we can calculate the cost
    of using FirstMatch strategy.
   */
  table_map firstmatch_need_tables;

  bool is_used;

  bool in_firstmatch_prefix() { return (first_firstmatch_table != MAX_TABLES); }
  void invalidate_firstmatch_prefix() { first_firstmatch_table= MAX_TABLES; }
public:
  void set_empty()
  {
    invalidate_firstmatch_prefix();
    is_used= FALSE;
  }

Monty's avatar
Monty committed
806
  void set_from_prev(POSITION *prev);
807 808 809 810 811 812 813 814
  bool check_qep(JOIN *join,
                 uint idx,
                 table_map remaining_tables, 
                 const JOIN_TAB *new_join_tab,
                 double *record_count,
                 double *read_time,
                 table_map *handled_fanout,
                 sj_strategy_enum *strategy,
Monty's avatar
Monty committed
815
                 POSITION *loose_scan_pos);
816 817 818 819 820 821 822 823

  void mark_used() { is_used= TRUE; }
  friend void fix_semijoin_strategies_for_picked_join_order(JOIN *join);
};


class LooseScan_picker : public Semi_join_strategy_picker
{
Monty's avatar
Monty committed
824
public:
825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848
  /* The first (i.e. driving) table we're doing loose scan for */
  uint        first_loosescan_table;
  /* 
     Tables that need to be in the prefix before we can calculate the cost
     of using LooseScan strategy.
  */
  table_map   loosescan_need_tables;

  /*
    keyno  -  Planning to do LooseScan on this key. If keyuse is NULL then 
              this is a full index scan, otherwise this is a ref+loosescan
              scan (and keyno matches the KEUSE's)
    MAX_KEY - Not doing a LooseScan
  */
  uint loosescan_key;  // final (one for strategy instance )
  uint loosescan_parts; /* Number of keyparts to be kept distinct */
  
  bool is_used;
  void set_empty()
  {
    first_loosescan_table= MAX_TABLES; 
    is_used= FALSE;
  }

Monty's avatar
Monty committed
849
  void set_from_prev(POSITION *prev);
850 851 852 853 854 855 856 857
  bool check_qep(JOIN *join,
                 uint idx,
                 table_map remaining_tables, 
                 const JOIN_TAB *new_join_tab,
                 double *record_count,
                 double *read_time,
                 table_map *handled_fanout,
                 sj_strategy_enum *strategy,
Monty's avatar
Monty committed
858
                 POSITION *loose_scan_pos);
859 860 861 862 863 864
  void mark_used() { is_used= TRUE; }

  friend class Loose_scan_opt;
  friend void best_access_path(JOIN      *join,
                               JOIN_TAB  *s,
                               table_map remaining_tables,
Monty's avatar
Monty committed
865
                               const POSITION *join_positions,
866 867 868
                               uint      idx,
                               bool      disable_jbuf,
                               double    record_count,
Monty's avatar
Monty committed
869 870
                               POSITION *pos,
                               POSITION *loose_scan_pos);
871
  friend bool get_best_combination(JOIN *join);
872
  friend int setup_semijoin_loosescan(JOIN *join);
873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893
  friend void fix_semijoin_strategies_for_picked_join_order(JOIN *join);
};


class Sj_materialization_picker : public Semi_join_strategy_picker
{
  bool is_used;

  /* The last inner table (valid once we're after it) */
  uint      sjm_scan_last_inner;
  /*
    Tables that we need to have in the prefix to calculate the correct cost.
    Basically, we need all inner tables and outer tables mentioned in the
    semi-join's ON expression so we can correctly account for fanout.
  */
  table_map sjm_scan_need_tables;

public:
  void set_empty()
  {
    sjm_scan_need_tables= 0;
894
    sjm_scan_last_inner= 0;
895 896
    is_used= FALSE;
  }
Monty's avatar
Monty committed
897
  void set_from_prev(POSITION *prev);
898 899 900 901 902 903 904 905
  bool check_qep(JOIN *join,
                 uint idx,
                 table_map remaining_tables, 
                 const JOIN_TAB *new_join_tab,
                 double *record_count,
                 double *read_time,
                 table_map *handled_fanout,
                 sj_strategy_enum *strategy,
Monty's avatar
Monty committed
906
                 POSITION *loose_scan_pos);
907 908 909 910 911
  void mark_used() { is_used= TRUE; }

  friend void fix_semijoin_strategies_for_picked_join_order(JOIN *join);
};

912

913 914
class Range_rowid_filter_cost_info;
class Rowid_filter;
915 916


unknown's avatar
unknown committed
917
/**
918 919 920
  Information about a position of table within a join order. Used in join
  optimization.
*/
Monty's avatar
Monty committed
921
class POSITION
922
{
Monty's avatar
Monty committed
923
public:
924 925 926
  /* The table that's put into join order */
  JOIN_TAB *table;

927 928 929 930 931
  /*
    The "fanout": number of output rows that will be produced (after
    pushed down selection condition is applied) per each row combination of
    previous tables.
  */
unknown's avatar
unknown committed
932
  double records_read;
933

Igor Babaev's avatar
Igor Babaev committed
934
  /* The selectivity of the pushed down conditions */
Monty's avatar
Monty committed
935
  double cond_selectivity;
Igor Babaev's avatar
Igor Babaev committed
936

937 938 939 940 941
  /* 
    Cost accessing the table in course of the entire complete join execution,
    i.e. cost of one access method use (e.g. 'range' or 'ref' scan ) times 
    number the access method will be invoked.
  */
942
  double read_time;
943 944

  double    prefix_record_count;
945 946 947 948 949

  /*
    NULL  -  'index' or 'range' or 'index_merge' or 'ALL' access is used.
    Other - [eq_]ref[_or_null] access is used. Pointer to {t.keypart1 = expr}
  */
unknown's avatar
unknown committed
950
  KEYUSE *key;
951

Monty's avatar
Monty committed
952 953 954 955 956 957
  /* Info on splitting plan used at this position */
  SplM_plan_info *spl_plan;

  /* Cost info for the range filter used at this position */
  Range_rowid_filter_cost_info *range_rowid_filter_info;

958 959
  /* If ref-based access is used: bitmap of tables this table depends on  */
  table_map ref_depend_map;
Monty's avatar
Monty committed
960

961
  /*
Monty's avatar
Monty committed
962 963 964
    Bitmap of semi-join inner tables that are in the join prefix and for
    which there's no provision for how to eliminate semi-join duplicates
    they produce.
965
  */
Monty's avatar
Monty committed
966 967 968 969 970 971 972 973 974 975 976 977
  table_map dups_producing_tables;

  table_map inner_tables_handled_with_other_sjs;

  Duplicate_weedout_picker  dups_weedout_picker;
  Firstmatch_picker         firstmatch_picker;
  LooseScan_picker          loosescan_picker;
  Sj_materialization_picker sjmat_picker;

  /* Cumulative cost and record count for the join prefix */
  Cost_estimate prefix_cost;

978 979 980
  /*
    Current optimization state: Semi-join strategy to be used for this
    and preceding join tables.
Monty's avatar
Monty committed
981

982
    Join optimizer sets this for the *last* join_tab in the
Monty's avatar
Monty committed
983
    duplicate-generating range. That is, in order to interpret this field,
984 985
    one needs to traverse join->[best_]positions array from right to left.
    When you see a join table with sj_strategy!= SJ_OPT_NONE, some other
Monty's avatar
Monty committed
986
    field (depending on the strategy) tells how many preceding positions
987 988 989
    this applies to. The values of covered_preceding_positions->sj_strategy
    must be ignored.
  */
990
  enum sj_strategy_enum sj_strategy;
Monty's avatar
Monty committed
991

992 993 994 995 996 997 998
  /*
    Valid only after fix_semijoin_strategies_for_picked_join_order() call:
    if sj_strategy!=SJ_OPT_NONE, this is the number of subsequent tables that
    are covered by the specified semi-join strategy
  */
  uint n_sj_tables;

999
  /*
Monty's avatar
Monty committed
1000 1001
    TRUE <=> join buffering will be used. At the moment this is based on
    *very* imprecise guesses made in best_access_path().
1002
  */
Monty's avatar
Monty committed
1003 1004 1005
  bool use_join_buffer;
  POSITION();
};
1006

1007 1008
typedef Bounds_checked_array<Item_null_result*> Item_null_array;

1009 1010 1011 1012
typedef struct st_rollup
{
  enum State { STATE_NONE, STATE_INITED, STATE_READY };
  State state;
1013 1014
  Item_null_array null_items;
  Ref_ptr_array *ref_pointer_arrays;
1015 1016 1017
  List<Item> *fields;
} ROLLUP;

unknown's avatar
unknown committed
1018

1019 1020 1021 1022 1023 1024 1025
class JOIN_TAB_RANGE: public Sql_alloc
{
public:
  JOIN_TAB *start;
  JOIN_TAB *end;
};

1026
class Pushdown_query;
unknown's avatar
unknown committed
1027

1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077
/**
  @brief
    Class to perform postjoin aggregation operations

  @details
    The result records are obtained on the put_record() call.
    The aggrgation process is determined by the write_func, it could be:
      end_write          Simply store all records in tmp table.
      end_write_group    Perform grouping using join->group_fields,
                         records are expected to be sorted.
      end_update         Perform grouping using the key generated on tmp
                         table. Input records aren't expected to be sorted.
                         Tmp table uses the heap engine
      end_update_unique  Same as above, but the engine is myisam.

    Lazy table initialization is used - the table will be instantiated and
    rnd/index scan started on the first put_record() call.

*/

class AGGR_OP :public Sql_alloc
{
public:
  JOIN_TAB *join_tab;

  AGGR_OP(JOIN_TAB *tab) : join_tab(tab), write_func(NULL)
  {};

  enum_nested_loop_state put_record() { return put_record(false); };
  /*
    Send the result of operation further (to a next operation/client)
    This function is called after all records were put into tmp table.

    @return return one of enum_nested_loop_state values.
  */
  enum_nested_loop_state end_send();
  /** write_func setter */
  void set_write_func(Next_select_func new_write_func)
  {
    write_func= new_write_func;
  }

private:
  /** Write function that would be used for saving records in tmp table. */
  Next_select_func write_func;
  enum_nested_loop_state put_record(bool end_of_records);
  bool prepare_tmp_table();
};


1078 1079
class JOIN :public Sql_alloc
{
1080
private:
unknown's avatar
unknown committed
1081 1082
  JOIN(const JOIN &rhs);                        /**< not implemented */
  JOIN& operator=(const JOIN &rhs);             /**< not implemented */
1083 1084

protected:
unknown's avatar
MWL#89  
unknown committed
1085 1086

  /**
unknown's avatar
MWL#89  
unknown committed
1087
    The subset of the state of a JOIN that represents an optimized query
1088 1089
    execution plan. Allows saving/restoring different JOIN plans for the same
    query.
unknown's avatar
MWL#89  
unknown committed
1090
  */
1091
  class Join_plan_state {
unknown's avatar
MWL#89  
unknown committed
1092
  public:
1093 1094
    DYNAMIC_ARRAY keyuse;        /* Copy of the JOIN::keyuse array. */
    POSITION *best_positions;    /* Copy of JOIN::best_positions */
unknown's avatar
MWL#89  
unknown committed
1095
    /* Copies of the JOIN_TAB::keyuse pointers for each JOIN_TAB. */
1096
    KEYUSE **join_tab_keyuse;
unknown's avatar
MWL#89  
unknown committed
1097
    /* Copies of JOIN_TAB::checked_keys for each JOIN_TAB. */
1098 1099 1100
    key_map *join_tab_checked_keys;
    SJ_MATERIALIZATION_INFO **sj_mat_info;
    my_bool error;
unknown's avatar
MWL#89  
unknown committed
1101
  public:
1102
    Join_plan_state(uint tables) : error(0)
unknown's avatar
MWL#89  
unknown committed
1103 1104 1105
    {   
      keyuse.elements= 0;
      keyuse.buffer= NULL;
1106
      keyuse.malloc_flags= 0;
1107
      best_positions= 0;                        /* To detect errors */
1108
      error= my_multi_malloc(PSI_INSTRUMENT_ME, MYF(MY_WME),
1109 1110 1111 1112 1113 1114 1115 1116 1117
                             &best_positions,
                             sizeof(*best_positions) * (tables + 1),
                             &join_tab_keyuse,
                             sizeof(*join_tab_keyuse) * tables,
                             &join_tab_checked_keys,
                             sizeof(*join_tab_checked_keys) * tables,
                             &sj_mat_info,
                             sizeof(sj_mat_info) * tables,
                             NullS) == 0;
unknown's avatar
MWL#89  
unknown committed
1118
    }
1119 1120
    Join_plan_state(JOIN *join);
    ~Join_plan_state()
unknown's avatar
MWL#89  
unknown committed
1121 1122
    {
      delete_dynamic(&keyuse);
unknown's avatar
unknown committed
1123
      my_free(best_positions);
unknown's avatar
MWL#89  
unknown committed
1124 1125 1126
    }
  };

1127 1128 1129 1130
  /* Results of reoptimizing a JOIN via JOIN::reoptimize(). */
  enum enum_reopt_result {
    REOPT_NEW_PLAN, /* there is a new reoptimized plan */
    REOPT_OLD_PLAN, /* no new improved plan can be found, use the old one */
1131
    REOPT_ERROR,    /* an irrecovarable error occurred during reoptimization */
1132 1133 1134
    REOPT_NONE      /* not yet reoptimized */
  };

1135
  /* Support for plan reoptimization with rewritten conditions. */
unknown's avatar
MWL#89  
unknown committed
1136
  enum_reopt_result reoptimize(Item *added_where, table_map join_tables,
1137
                               Join_plan_state *save_to);
1138 1139
  /* Choose a subquery plan for a table-less subquery. */
  bool choose_tableless_subquery_plan();
1140
  void handle_implicit_grouping_with_window_funcs();
1141 1142

public:
1143
  void save_query_plan(Join_plan_state *save_to);
unknown's avatar
unknown committed
1144
  void reset_query_plan();
1145
  void restore_query_plan(Join_plan_state *restore_from);
1146

unknown's avatar
unknown committed
1147
public:
1148
  JOIN_TAB *join_tab, **best_ref;
1149

1150 1151 1152
  /* List of fields that aren't under an aggregate function */
  List<Item_field> non_agg_fields;

unknown's avatar
unknown committed
1153
  JOIN_TAB **map2table;    ///< mapping between table indexes and JOIN_TABs
1154 1155
  List<JOIN_TAB_RANGE> join_tab_ranges;
  
1156 1157
  /*
    Base tables participating in the join. After join optimization is done, the
1158 1159
    tables are stored in the join order (but the only really important part is 
    that const tables are first).
1160
  */
1161 1162 1163 1164 1165 1166 1167
  TABLE    **table;
  /**
    The table which has an index that allows to produce the requried ordering.
    A special value of 0x1 means that the ordering will be produced by
    passing 1st non-const table to filesort(). NULL means no such table exists.
  */
  TABLE    *sort_by_table;
1168 1169 1170 1171 1172 1173 1174
  /* 
    Number of tables in the join. 
    (In MySQL, it is named 'tables' and is also the number of elements in 
     join->join_tab array. In MariaDB, the latter is not true, so we've renamed
     the variable)
  */
  uint	   table_count;
1175 1176
  uint     outer_tables;  /**< Number of tables that are not inside semijoin */
  uint     const_tables;
1177 1178 1179 1180 1181 1182
  /* 
    Number of tables in the top join_tab array. Normally this matches
    (join_tab_ranges.head()->end - join_tab_ranges.head()->start). 
    
    We keep it here so that it is saved/restored with JOIN::restore_tmp.
  */
1183
  uint     top_join_tab_count;
1184
  uint     aggr_tables;     ///< Number of post-join tmp tables 
unknown's avatar
unknown committed
1185
  uint	   send_group_parts;
1186 1187 1188 1189 1190 1191 1192 1193 1194 1195
  /*
    This represents the number of items in ORDER BY *after* removing
    all const items. This is computed before other optimizations take place,
    such as removal of ORDER BY when it is a prefix of GROUP BY, for example:
    GROUP BY a, b ORDER BY a

    This is used when deciding to send rows, by examining the correct number
    of items in the group_fields list when ORDER BY was previously eliminated.
  */
  uint with_ties_order_count;
Sergei Petrunia's avatar
Sergei Petrunia committed
1196 1197 1198 1199 1200 1201 1202
  /*
    True if the query has GROUP BY.
    (that is, if group_by != NULL. when DISTINCT is converted into GROUP BY, it
     will set this, too. It is not clear why we need a separate var from 
     group_list)
  */
  bool	   group;
Sergei Golubchik's avatar
Sergei Golubchik committed
1203 1204
  bool     need_distinct;

1205 1206 1207 1208 1209 1210 1211
  /**
    Indicates that grouping will be performed on the result set during
    query execution. This field belongs to query execution.

    @see make_group_fields, alloc_group_fields, JOIN::exec
  */
  bool     sort_and_group; 
1212
  bool     first_record,full_join, no_field_update;
Igor Babaev's avatar
Igor Babaev committed
1213
  bool     hash_join;
1214
  bool	   do_send_rows;
Sergey Petrunya's avatar
Sergey Petrunya committed
1215
  table_map const_table_map;
Igor Babaev's avatar
Igor Babaev committed
1216 1217 1218 1219 1220
  /** 
    Bitmap of semijoin tables that the current partial plan decided
    to materialize and access by lookups
  */
  table_map sjm_lookup_tables;
Igor Babaev's avatar
Igor Babaev committed
1221 1222 1223 1224 1225
  /** 
    Bitmap of semijoin tables that the chosen plan decided
    to materialize to scan the results of materialization
  */
  table_map sjm_scan_tables;
Sergey Petrunya's avatar
Sergey Petrunya committed
1226 1227 1228 1229 1230
  /*
    Constant tables for which we have found a row (as opposed to those for
    which we didn't).
  */
  table_map found_const_table_map;
Sergey Petrunia's avatar
Sergey Petrunia committed
1231 1232
  
  /* Tables removed by table elimination. Set to 0 before the elimination. */
Sergey Petrunia's avatar
Sergey Petrunia committed
1233
  table_map eliminated_tables;
1234
  /*
1235 1236
     Bitmap of all inner tables from outer joins (set at start of
     make_join_statistics)
1237 1238
  */
  table_map outer_join;
Igor Babaev's avatar
Igor Babaev committed
1239 1240
  /* Bitmap of tables used in the select list items */
  table_map select_list_used_tables;
1241
  ha_rows  send_records,found_records,join_examined_rows, accepted_rows;
Sergei Petrunia's avatar
Sergei Petrunia committed
1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254

  /*
    LIMIT for the JOIN operation. When not using aggregation or DISITNCT, this 
    is the same as select's LIMIT clause specifies.
    Note that this doesn't take sql_calc_found_rows into account.
  */
  ha_rows row_limit;

  /*
    How many output rows should be produced after GROUP BY.
    (if sql_calc_found_rows is used, LIMIT is ignored)
  */
  ha_rows select_limit;
1255 1256 1257 1258
  /*
    Number of duplicate rows found in UNION.
  */
  ha_rows duplicate_rows;
unknown's avatar
unknown committed
1259
  /**
unknown's avatar
unknown committed
1260
    Used to fetch no more than given amount of rows per one
1261 1262 1263 1264 1265 1266
    fetch operation of server side cursor.
    The value is checked in end_send and end_send_group in fashion, similar
    to offset_limit_cnt:
      - fetch_limit= HA_POS_ERROR if there is no cursor.
      - when we open a cursor, we set fetch_limit to 0,
      - on each fetch iteration we add num_rows to fetch to fetch_limit
Sergei Petrunia's avatar
Sergei Petrunia committed
1267
    NOTE: currently always HA_POS_ERROR.
1268 1269
  */
  ha_rows  fetch_limit;
Sergei Petrunia's avatar
Sergei Petrunia committed
1270

1271
  /* Finally picked QEP. This is result of join optimization */
1272
  POSITION *best_positions;
1273

1274
  Pushdown_query *pushdown_query;
1275 1276 1277
  JOIN_TAB *original_join_tab;
  uint	   original_table_count;

1278 1279 1280 1281 1282 1283
/******* Join optimization state members start *******/
  /*
    pointer - we're doing optimization for a semi-join materialization nest.
    NULL    - otherwise
  */
  TABLE_LIST *emb_sjm_nest;
1284
  
1285
  /* Current join optimization state */
1286
  POSITION *positions;
1287 1288
  
  /*
1289 1290 1291 1292
    Bitmap of nested joins embedding the position at the end of the current 
    partial join (valid only during join optimizer run).
  */
  nested_join_map cur_embedding_map;
1293 1294 1295 1296 1297 1298 1299 1300 1301 1302
  
  /*
    Bitmap of inner tables of semi-join nests that have a proper subset of
    their tables in the current join prefix. That is, of those semi-join
    nests that have their tables both in and outside of the join prefix.
  */
  table_map cur_sj_inner_tables;
  
  /* We also maintain a stack of join optimization states in * join->positions[] */
/******* Join optimization state members end *******/
1303 1304 1305 1306 1307 1308 1309

  /*
    Tables within complex firstmatch ranges (i.e. those where inner tables are
    interleaved with outer tables). Join buffering cannot be used for these.
  */
  table_map complex_firstmatch_tables;

1310
  Next_select_func first_select;
1311 1312 1313 1314 1315
  /*
    The cost of best complete join plan found so far during optimization,
    after optimization phase - cost of picked join order (not taking into
    account the changes made by test_if_skip_sort_order()).
  */
unknown's avatar
unknown committed
1316
  double   best_read;
unknown's avatar
MWL#89  
unknown committed
1317
  /*
1318
    Estimated result rows (fanout) of the join operation. If this is a subquery
unknown's avatar
MWL#89  
unknown committed
1319 1320 1321 1322
    that is reexecuted multiple times, this value includes the estiamted # of
    reexecutions. This value is equal to the multiplication of all
    join->positions[i].records_read of a JOIN.
  */
1323
  double   join_record_count;
unknown's avatar
unknown committed
1324
  List<Item> *fields;
1325 1326 1327 1328

  /* Used only for FETCH ... WITH TIES to identify peers. */
  List<Cached_item> order_fields;
  /* Used during GROUP BY operations to identify when a group has changed. */
unknown's avatar
unknown committed
1329
  List<Cached_item> group_fields, group_fields_cache;
unknown's avatar
unknown committed
1330
  THD	   *thd;
1331
  Item_sum  **sum_funcs, ***sum_funcs_end;
unknown's avatar
unknown committed
1332
  /** second copy of sumfuncs (for queries with 2 temporary tables */
1333
  Item_sum  **sum_funcs2, ***sum_funcs_end2;
unknown's avatar
unknown committed
1334 1335
  Procedure *procedure;
  Item	    *having;
unknown's avatar
unknown committed
1336 1337
  Item      *tmp_having; ///< To store having when processed temporary table
  Item      *having_history; ///< Store having for explain
1338 1339
  ORDER     *group_list_for_estimates;
  bool      having_is_correlated;
1340
  ulonglong  select_options;
1341 1342 1343 1344 1345 1346 1347 1348 1349
  /* 
    Bitmap of allowed types of the join caches that
    can be used for join operations
  */
  uint allowed_join_cache_types;
  bool allowed_semijoin_with_cache;
  bool allowed_outer_join_with_cache;
  /* Maximum level of the join caches that can be used for join operations */ 
  uint max_allowed_join_cache_level;
unknown's avatar
unknown committed
1350 1351 1352
  select_result *result;
  TMP_TABLE_PARAM tmp_table_param;
  MYSQL_LOCK *lock;
unknown's avatar
unknown committed
1353
  /// unit structure (with global parameters) for this select
1354
  SELECT_LEX_UNIT *unit;
unknown's avatar
unknown committed
1355
  /// select that processed
1356
  SELECT_LEX *select_lex;
unknown's avatar
unknown committed
1357
  /** 
1358 1359 1360 1361 1362 1363 1364
    TRUE <=> optimizer must not mark any table as a constant table.
    This is needed for subqueries in form "a IN (SELECT .. UNION SELECT ..):
    when we optimize the select that reads the results of the union from a
    temporary table, we must not mark the temp. table as constant because
    the number of rows in it may vary from one subquery execution to another.
  */
  bool no_const_tables; 
1365 1366 1367 1368 1369
  /*
    This flag is set if we call no_rows_in_result() as par of end_group().
    This is used as a simple speed optimization to avoiding calling
    restore_no_rows_in_result() in ::reinit()
  */
1370
  bool no_rows_in_result_called;
1371 1372 1373 1374 1375 1376

  /**
    This is set if SQL_CALC_ROWS was calculated by filesort()
    and should be taken from the appropriate JOIN_TAB
  */
  bool filesort_found_rows;
1377 1378

  bool subq_exit_fl;
1379
  
unknown's avatar
unknown committed
1380
  ROLLUP rollup;				///< Used with rollup
1381 1382
  
  bool mixed_implicit_grouping;
unknown's avatar
unknown committed
1383 1384
  bool select_distinct;				///< Set if SELECT DISTINCT
  /**
1385 1386 1387 1388 1389 1390 1391
    If we have the GROUP BY statement in the query,
    but the group_list was emptied by optimizer, this
    flag is TRUE.
    It happens when fields in the GROUP BY are from
    constant table
  */
  bool group_optimized_away;
unknown's avatar
unknown committed
1392 1393 1394 1395 1396

  /*
    simple_xxxxx is set if ORDER/GROUP BY doesn't include any references
    to other tables than the first non-constant table in the JOIN.
    It's also set if ORDER/GROUP BY is empty.
1397 1398
    Used for deciding for or against using a temporary table to compute 
    GROUP/ORDER BY.
unknown's avatar
unknown committed
1399 1400
  */
  bool simple_order, simple_group;
1401 1402 1403 1404 1405
  /*
    Set to 1 if any field in field list has RAND_TABLE set. For example if
    if one uses RAND() or ROWNUM() in field list
  */
  bool rand_table_in_field_list;
1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418

  /*
    ordered_index_usage is set if an ordered index access
    should be used instead of a filesort when computing 
    ORDER/GROUP BY.
  */
  enum
  {
    ordered_index_void,       // No ordered index avail.
    ordered_index_group_by,   // Use index for GROUP BY
    ordered_index_order_by    // Use index for ORDER BY
  } ordered_index_usage;

unknown's avatar
unknown committed
1419
  /**
unknown's avatar
unknown committed
1420 1421 1422 1423
    Is set only in case if we have a GROUP BY clause
    and no ORDER BY after constant elimination of 'order'.
  */
  bool no_order;
unknown's avatar
unknown committed
1424
  /** Is set if we have a GROUP BY and we have ORDER BY on a constant. */
unknown's avatar
unknown committed
1425 1426
  bool          skip_sort_order;

1427 1428
  bool need_tmp; 
  bool hidden_group_fields;
1429 1430
  /* TRUE if there was full cleunap of the JOIN */
  bool cleaned;
1431
  DYNAMIC_ARRAY keyuse;
1432
  Item::cond_result cond_value, having_value;
Igor Babaev's avatar
Igor Babaev committed
1433 1434 1435 1436 1437
  /**
    Impossible where after reading const tables 
    (set in make_join_statistics())
  */
  bool impossible_where; 
unknown's avatar
unknown committed
1438 1439
  List<Item> all_fields; ///< to store all fields that used in query
  ///Above list changed to use temporary table
1440
  List<Item> tmp_all_fields1, tmp_all_fields2, tmp_all_fields3;
unknown's avatar
unknown committed
1441
  ///Part, shared with list above, emulate following list
1442
  List<Item> tmp_fields_list1, tmp_fields_list2, tmp_fields_list3;
unknown's avatar
unknown committed
1443
  List<Item> &fields_list; ///< hold field list passed to mysql_select
1444
  List<Item> procedure_fields_list;
1445 1446 1447 1448
  int error;

  ORDER *order, *group_list, *proc_param; //hold parameters of mysql_select
  COND *conds;                            // ---"---
unknown's avatar
unknown committed
1449
  Item *conds_history;                    // store WHERE for explain
Igor Babaev's avatar
Igor Babaev committed
1450
  COND *outer_ref_cond;       ///<part of conds containing only outer references
1451
  COND *pseudo_bits_cond;     // part of conds containing special bita
unknown's avatar
unknown committed
1452 1453
  TABLE_LIST *tables_list;           ///<hold 'tables' parameter of mysql_select
  List<TABLE_LIST> *join_list;       ///< list of joined tables in reverse order
1454
  COND_EQUAL *cond_equal;
1455
  COND_EQUAL *having_equal;
1456 1457 1458 1459 1460 1461
  /*
    Constant codition computed during optimization, but evaluated during
    join execution. Typically expensive conditions that should not be
    evaluated at optimization time.
  */
  Item *exec_const_cond;
unknown's avatar
unknown committed
1462 1463 1464 1465 1466 1467 1468
  /*
    Constant ORDER and/or GROUP expressions that contain subqueries. Such
    expressions need to evaluated to verify that the subquery indeed
    returns a single row. The evaluation of such expressions is delayed
    until query execution.
  */
  List<Item> exec_const_order_group_cond;
unknown's avatar
unknown committed
1469 1470
  SQL_SELECT *select;                ///<created in optimisation phase
  JOIN_TAB *return_tab;              ///<used only for outer joins
1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483

  /*
    Used pointer reference for this select.
    select_lex->ref_pointer_array contains five "slices" of the same length:
    |========|========|========|========|========|
     ref_ptrs items0   items1   items2   items3
   */
  Ref_ptr_array ref_ptrs;
  // Copy of the initial slice above, to be used with different lists
  Ref_ptr_array items0, items1, items2, items3;
  // Used by rollup, to restore ref_ptrs after overwriting it.
  Ref_ptr_array current_ref_ptrs;

unknown's avatar
unknown committed
1484
  const char *zero_result_cause; ///< not 0 if exec must return zero result
unknown's avatar
unknown committed
1485
  
unknown's avatar
unknown committed
1486
  bool union_part; ///< this subselect is part of union 
1487 1488 1489

  enum join_optimization_state { NOT_OPTIMIZED=0,
                                 OPTIMIZATION_IN_PROGRESS=1,
Igor Babaev's avatar
Igor Babaev committed
1490
                                 OPTIMIZATION_PHASE_1_DONE=2,
1491
                                 OPTIMIZATION_DONE=3};
1492 1493
  // state of JOIN optimization
  enum join_optimization_state optimization_state;
1494
  bool initialized; ///< flag to avoid double init_execution calls
1495

1496
  Explain_select *explain;
1497 1498
  
  enum { QEP_NOT_PRESENT_YET, QEP_AVAILABLE, QEP_DELETED} have_query_plan;
1499

1500 1501 1502
  // if keep_current_rowid=true, whether they should be saved in temporary table
  bool tmp_table_keep_current_rowid;

1503 1504 1505 1506 1507 1508
  /*
    Additional WHERE and HAVING predicates to be considered for IN=>EXISTS
    subquery transformation of a JOIN object.
  */
  Item *in_to_exists_where;
  Item *in_to_exists_having;
1509
  
1510 1511
  /* Temporary tables used to weed-out semi-join duplicates */
  List<TABLE> sj_tmp_tables;
Sergey Petrunya's avatar
Sergey Petrunya committed
1512
  /* SJM nests that are executed with SJ-Materialization strategy */
1513 1514
  List<SJ_MATERIALIZATION_INFO> sjm_info_list;

1515 1516 1517 1518
  /** TRUE <=> ref_pointer_array is set to items3. */
  bool set_group_rpa;
  /** Exec time only: TRUE <=> current group has been sent */
  bool group_sent;
1519 1520 1521 1522 1523
  /**
    TRUE if the query contains an aggregate function but has no GROUP
    BY clause. 
  */
  bool implicit_grouping; 
1524

1525
  bool with_two_phase_optimization;
1526 1527 1528 1529 1530 1531 1532

  /* Saved execution plan for this join */
  Join_plan_state *save_qep;
  /* Info on splittability of the table materialized by this plan*/
  SplM_opt_info *spl_opt_info;
  /* Contains info on keyuses usable for splitting */
  Dynamic_array<KEYUSE_EXT> *ext_keyuses_for_splitting;
1533

1534
  JOIN_TAB *sort_and_group_aggr_tab;
1535 1536 1537 1538 1539
  /*
    Flag is set to true if select_lex was found to be degenerated before
    the optimize_cond() call in JOIN::optimize_inner() method.
  */
  bool is_orig_degenerated;
1540

1541
  JOIN(THD *thd_arg, List<Item> &fields_arg, ulonglong select_options_arg,
1542
       select_result *result_arg)
Igor Babaev's avatar
Igor Babaev committed
1543
    :fields_list(fields_arg)
1544
  {
1545
    init(thd_arg, fields_arg, select_options_arg, result_arg);
1546
  }
1547

1548
  void init(THD *thd_arg, List<Item> &fields_arg, ulonglong select_options_arg,
1549 1550
       select_result *result_arg)
  {
1551
    join_tab= 0;
1552
    table= 0;
1553
    table_count= 0;
1554
    top_join_tab_count= 0;
1555
    const_tables= 0;
1556
    const_table_map= found_const_table_map= 0;
1557
    aggr_tables= 0;
Sergey Petrunia's avatar
Sergey Petrunia committed
1558
    eliminated_tables= 0;
1559
    join_list= 0;
1560
    implicit_grouping= FALSE;
1561 1562 1563
    sort_and_group= 0;
    first_record= 0;
    do_send_rows= 1;
1564
    duplicate_rows= send_records= 0;
1565
    found_records= accepted_rows= 0;
1566
    fetch_limit= HA_POS_ERROR;
1567
    thd= thd_arg;
unknown's avatar
merge  
unknown committed
1568
    sum_funcs= sum_funcs2= 0;
1569
    procedure= 0;
unknown's avatar
unknown committed
1570
    having= tmp_having= having_history= 0;
1571 1572
    having_is_correlated= false;
    group_list_for_estimates= 0;
1573 1574 1575 1576
    select_options= select_options_arg;
    result= result_arg;
    lock= thd_arg->lock;
    select_lex= 0; //for safety
1577
    select_distinct= MY_TEST(select_options & SELECT_DISTINCT);
1578 1579 1580
    no_order= 0;
    simple_order= 0;
    simple_group= 0;
1581
    rand_table_in_field_list= 0;
1582
    ordered_index_usage= ordered_index_void;
Sergei Golubchik's avatar
Sergei Golubchik committed
1583
    need_distinct= 0;
1584
    skip_sort_order= 0;
1585
    with_two_phase_optimization= 0;
1586 1587 1588 1589
    save_qep= 0;
    spl_opt_info= 0;
    ext_keyuses_for_splitting= 0;
    spl_opt_info= 0;
1590 1591 1592 1593
    need_tmp= 0;
    hidden_group_fields= 0; /*safety*/
    error= 0;
    select= 0;
1594
    return_tab= 0;
1595 1596 1597 1598 1599
    ref_ptrs.reset();
    items0.reset();
    items1.reset();
    items2.reset();
    items3.reset();
1600
    zero_result_cause= 0;
1601
    optimization_state= JOIN::NOT_OPTIMIZED;
1602
    have_query_plan= QEP_NOT_PRESENT_YET;
1603
    initialized= 0;
1604
    cleaned= 0;
1605
    cond_equal= 0;
1606
    having_equal= 0;
1607
    exec_const_cond= 0;
1608
    group_optimized_away= 0;
1609
    no_rows_in_result_called= 0;
1610
    positions= best_positions= 0;
1611
    pushdown_query= 0;
1612
    original_join_tab= 0;
1613
    explain= NULL;
1614
    tmp_table_keep_current_rowid= 0;
1615

unknown's avatar
unknown committed
1616
    all_fields= fields_arg;
1617 1618
    if (&fields_list != &fields_arg)      /* Avoid valgrind-warning */
      fields_list= fields_arg;
1619
    non_agg_fields.empty();
1620
    bzero((char*) &keyuse,sizeof(keyuse));
Monty's avatar
Monty committed
1621
    having_value= Item::COND_UNDEF;
1622
    tmp_table_param.init();
1623
    tmp_table_param.end_write_records= HA_POS_ERROR;
1624
    rollup.state= ROLLUP::STATE_NONE;
1625 1626

    no_const_tables= FALSE;
1627 1628 1629 1630
    first_select= sub_select;
    set_group_rpa= false;
    group_sent= 0;

1631
    outer_ref_cond= pseudo_bits_cond= NULL;
1632 1633
    in_to_exists_where= NULL;
    in_to_exists_having= NULL;
Igor Babaev's avatar
Igor Babaev committed
1634 1635
    emb_sjm_nest= NULL;
    sjm_lookup_tables= 0;
Igor Babaev's avatar
Igor Babaev committed
1636
    sjm_scan_tables= 0;
1637
    is_orig_degenerated= false;
1638 1639

    with_ties_order_count= 0;
1640
  }
1641

1642 1643
  /* True if the plan guarantees that it will be returned zero or one row */
  bool only_const_tables()  { return const_tables == table_count; }
Igor Babaev's avatar
Igor Babaev committed
1644 1645
  /* Number of tables actually joined at the top level */
  uint exec_join_tab_cnt() { return tables_list ? top_join_tab_count : 0; }
1646

1647 1648 1649 1650 1651 1652 1653 1654 1655
  /*
    Number of tables in the join which also includes the temporary tables
    created for GROUP BY, DISTINCT , WINDOW FUNCTION etc.
  */
  uint total_join_tab_cnt()
  {
    return exec_join_tab_cnt() + aggr_tables - 1;
  }

1656 1657 1658
  int prepare(TABLE_LIST *tables, COND *conds, uint og_num, ORDER *order,
              bool skip_order_by, ORDER *group, Item *having,
              ORDER *proc_param, SELECT_LEX *select, SELECT_LEX_UNIT *unit);
1659
  bool prepare_stage2();
1660
  int optimize();
1661
  int optimize_inner();
1662
  int optimize_stage2();
1663
  bool build_explain();
unknown's avatar
unknown committed
1664
  int reinit();
1665
  int init_execution();
1666
  void exec();
1667

1668
  void exec_inner();
1669
  bool prepare_result(List<Item> **columns_list);
1670
  int destroy();
1671
  void restore_tmp();
1672
  bool alloc_func_list();
1673
  bool flatten_subqueries();
1674
  bool optimize_unflattened_subqueries();
unknown's avatar
unknown committed
1675
  bool optimize_constant_subqueries();
1676 1677
  bool make_range_rowid_filters();
  bool init_range_rowid_filters();
1678
  bool make_sum_func_list(List<Item> &all_fields, List<Item> &send_fields,
1679
			  bool before_group_by, bool recompute= FALSE);
1680

1681 1682
  /// Initialzes a slice, see comments for ref_ptrs above.
  Ref_ptr_array ref_ptr_array_slice(size_t slice_num)
1683
  {
1684 1685 1686 1687 1688
    size_t slice_sz= select_lex->ref_pointer_array.size() / 5U;
    DBUG_ASSERT(select_lex->ref_pointer_array.size() % 5 == 0);
    DBUG_ASSERT(slice_num < 5U);
    return Ref_ptr_array(&select_lex->ref_pointer_array[slice_num * slice_sz],
                         slice_sz);
1689
  }
1690 1691 1692 1693 1694 1695 1696 1697 1698

  /**
     Overwrites one slice with the contents of another slice.
     In the normal case, dst and src have the same size().
     However: the rollup slices may have smaller size than slice_sz.
   */
  void copy_ref_ptr_array(Ref_ptr_array dst_arr, Ref_ptr_array src_arr)
  {
    DBUG_ASSERT(dst_arr.size() >= src_arr.size());
1699 1700 1701
    if (src_arr.size() == 0)
      return;

1702 1703 1704 1705 1706 1707 1708
    void *dest= dst_arr.array();
    const void *src= src_arr.array();
    memcpy(dest, src, src_arr.size() * src_arr.element_size());
  }

  /// Overwrites 'ref_ptrs' and remembers the the source as 'current'.
  void set_items_ref_array(Ref_ptr_array src_arr)
1709
  {
1710 1711 1712 1713 1714 1715 1716 1717 1718 1719
    copy_ref_ptr_array(ref_ptrs, src_arr);
    current_ref_ptrs= src_arr;
  }

  /// Initializes 'items0' and remembers that it is 'current'.
  void init_items_ref_array()
  {
    items0= ref_ptr_array_slice(1);
    copy_ref_ptr_array(items0, ref_ptrs);
    current_ref_ptrs= items0;
1720
  }
1721 1722

  bool rollup_init();
1723
  bool rollup_process_const_fields();
1724 1725
  bool rollup_make_fields(List<Item> &all_fields, List<Item> &fields,
			  Item_sum ***func);
1726
  int rollup_send_data(uint idx);
1727
  int rollup_write_data(uint idx, TMP_TABLE_PARAM *tmp_table_param, TABLE *table);
1728
  void join_free();
unknown's avatar
unknown committed
1729
  /** Cleanup this JOIN, possibly for reuse */
1730
  void cleanup(bool full);
1731
  void clear();
1732 1733
  bool send_row_on_empty_set()
  {
unknown's avatar
MWL#89  
unknown committed
1734
    return (do_send_rows && implicit_grouping && !group_optimized_away &&
unknown's avatar
unknown committed
1735
            having_value != Item::COND_FALSE);
1736
  }
unknown's avatar
unknown committed
1737
  bool empty_result() { return (zero_result_cause && !implicit_grouping); }
1738
  bool change_result(select_result *new_result, select_result *old_result);
1739 1740 1741 1742 1743
  bool is_top_level_join() const
  {
    return (unit == &thd->lex->unit && (unit->fake_select_lex == 0 ||
                                        select_lex == unit->fake_select_lex));
  }
1744
  void cache_const_exprs();
Sergey Petrunya's avatar
Sergey Petrunya committed
1745 1746
  inline table_map all_tables_map()
  {
1747
    return (table_map(1) << table_count) - 1;
Sergey Petrunya's avatar
Sergey Petrunya committed
1748
  }
1749
  void drop_unused_derived_keys();
1750 1751
  bool get_best_combination();
  bool add_sorting_to_table(JOIN_TAB *tab, ORDER *order);
Igor Babaev's avatar
Igor Babaev committed
1752
  inline void eval_select_list_used_tables();
1753 1754 1755 1756 1757 1758 1759 1760 1761 1762
  /* 
    Return the table for which an index scan can be used to satisfy 
    the sort order needed by the ORDER BY/(implicit) GROUP BY clause 
  */
  JOIN_TAB *get_sort_by_join_tab()
  {
    return (need_tmp || !sort_by_table || skip_sort_order ||
            ((group || tmp_table_param.sum_func_count) && !group_list)) ?
              NULL : join_tab+const_tables;
  }
unknown's avatar
unknown committed
1763
  bool setup_subquery_caches();
1764 1765 1766
  bool shrink_join_buffers(JOIN_TAB *jt, 
                           ulonglong curr_space,
                           ulonglong needed_space);
1767 1768 1769
  void set_allowed_join_cache_types();
  bool is_allowed_hash_join_access()
  { 
1770
    return MY_TEST(allowed_join_cache_types & JOIN_CACHE_HASHED_BIT) &&
1771 1772
           max_allowed_join_cache_level > JOIN_CACHE_HASHED_BIT;
  }
Igor Babaev's avatar
Igor Babaev committed
1773 1774 1775 1776 1777 1778 1779 1780
  /*
    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.
1781
    - We are using WINDOW functions.
Igor Babaev's avatar
Igor Babaev committed
1782 1783 1784 1785 1786 1787 1788 1789
    When the WITH ROLLUP modifier is present, we cannot skip temporary table
    creation for the DISTINCT clause just because there are only const tables.
  */
  bool test_if_need_tmp_table()
  {
    return ((const_tables != table_count &&
	    ((select_distinct || !simple_order || !simple_group) ||
	     (group_list && order) ||
1790
             MY_TEST(select_options & OPTION_BUFFER_RESULT))) ||
1791 1792
            (rollup.state != ROLLUP::STATE_NONE && select_distinct) ||
            select_lex->have_window_funcs());
Igor Babaev's avatar
Igor Babaev committed
1793
  }
1794
  bool choose_subquery_plan(table_map join_tables);
1795
  void get_partial_cost_and_fanout(int end_tab_idx,
Sergey Petrunya's avatar
Sergey Petrunya committed
1796 1797 1798
                                   table_map filter_map,
                                   double *read_time_arg, 
                                   double *record_count_arg);
Sergey Petrunya's avatar
Sergey Petrunya committed
1799 1800 1801
  void get_prefix_cost_and_fanout(uint n_tables, 
                                  double *read_time_arg,
                                  double *record_count_arg);
unknown's avatar
unknown committed
1802
  double get_examined_rows();
1803 1804
  /* defined in opt_subselect.cc */
  bool transform_max_min_subquery();
1805 1806 1807 1808 1809
  /* True if this JOIN is a subquery under an IN predicate. */
  bool is_in_subquery()
  {
    return (unit->item && unit->item->is_in_predicate());
  }
1810
  bool save_explain_data(Explain_query *output, bool can_overwrite,
1811 1812 1813 1814
                         bool need_tmp_table, bool need_order, bool distinct);
  int save_explain_data_intern(Explain_query *output, bool need_tmp_table,
                               bool need_order, bool distinct,
                               const char *message);
1815
  JOIN_TAB *first_breadth_first_tab() { return join_tab; }
1816 1817
  bool check_two_phase_optimization(THD *thd);
  bool inject_cond_into_where(Item *injected_cond);
1818 1819 1820 1821
  bool check_for_splittable_materialized();
  void add_keyuses_for_splitting();
  bool inject_best_splitting_cond(table_map remaining_tables);
  bool fix_all_splittings_in_plan();
1822
  void make_notnull_conds_for_range_scans();
1823

1824
  bool transform_in_predicates_into_in_subq(THD *thd);
1825 1826 1827

  bool optimize_upper_rownum_func();

1828
private:
1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857
  /**
    Create a temporary table to be used for processing DISTINCT/ORDER
    BY/GROUP BY.

    @note Will modify JOIN object wrt sort/group attributes

    @param tab              the JOIN_TAB object to attach created table to
    @param tmp_table_fields List of items that will be used to define
                            column types of the table.
    @param tmp_table_group  Group key to use for temporary table, NULL if none.
    @param save_sum_fields  If true, do not replace Item_sum items in 
                            @c tmp_fields list with Item_field items referring 
                            to fields in temporary table.

    @returns false on success, true on failure
  */
  bool create_postjoin_aggr_table(JOIN_TAB *tab, List<Item> *tmp_table_fields,
                                  ORDER *tmp_table_group,
                                  bool save_sum_fields,
                                  bool distinct,
                                  bool keep_row_ordermake);
  /**
    Optimize distinct when used on a subset of the tables.

    E.g.,: 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
  */
  void optimize_distinct();

1858
  void cleanup_item_list(List<Item> &items) const;
1859
  bool add_having_as_table_cond(JOIN_TAB *tab);
1860
  bool make_aggr_tables_info();
1861
  bool add_fields_for_current_rowid(JOIN_TAB *cur, List<Item> *fields);
1862
  void init_join_cache_and_keyread();
unknown's avatar
unknown committed
1863 1864
};

1865 1866
enum enum_with_bush_roots { WITH_BUSH_ROOTS, WITHOUT_BUSH_ROOTS};
enum enum_with_const_tables { WITH_CONST_TABLES, WITHOUT_CONST_TABLES};
unknown's avatar
unknown committed
1867

Sergei Golubchik's avatar
Sergei Golubchik committed
1868
JOIN_TAB *first_linear_tab(JOIN *join,
1869 1870
                           enum enum_with_bush_roots include_bush_roots,
                           enum enum_with_const_tables const_tbls);
1871 1872
JOIN_TAB *next_linear_tab(JOIN* join, JOIN_TAB* tab, 
                          enum enum_with_bush_roots include_bush_roots);
unknown's avatar
unknown committed
1873

1874 1875
JOIN_TAB *first_top_level_tab(JOIN *join, enum enum_with_const_tables with_const);
JOIN_TAB *next_top_level_tab(JOIN *join, JOIN_TAB *tab);
unknown's avatar
unknown committed
1876 1877 1878 1879 1880 1881 1882 1883

typedef struct st_select_check {
  uint const_ref,reg_ref;
} SELECT_CHECK;

extern const char *join_type_str[];

/* Extern functions in sql_select.cc */
1884 1885
void count_field_types(SELECT_LEX *select_lex, TMP_TABLE_PARAM *param, 
                       List<Item> &fields, bool reset_with_sum_func);
1886
bool setup_copy_fields(THD *thd, TMP_TABLE_PARAM *param,
1887
		       Ref_ptr_array ref_pointer_array,
1888 1889
		       List<Item> &new_list1, List<Item> &new_list2,
		       uint elements, List<Item> &fields);
unknown's avatar
unknown committed
1890
void copy_fields(TMP_TABLE_PARAM *param);
1891
bool copy_funcs(Item **func_ptr, const THD *thd);
unknown's avatar
unknown committed
1892
uint find_shortest_key(TABLE *table, const key_map *usable_keys);
1893 1894
bool is_indexed_agg_distinct(JOIN *join, List<Item_field> *out_args);

unknown's avatar
unknown committed
1895
/* functions from opt_sum.cc */
1896
bool simple_pred(Item_func *func_item, Item **args, bool *inv_order);
1897
int opt_sum_query(THD* thd,
Igor Babaev's avatar
Merge  
Igor Babaev committed
1898
                  List<TABLE_LIST> &tables, List<Item> &all_fields, COND *conds);
unknown's avatar
unknown committed
1899

1900
/* from sql_delete.cc, used by opt_range.cc */
1901
extern "C" int refpos_order_cmp(void* arg, const void *a,const void *b);
1902

unknown's avatar
unknown committed
1903
/** class to copying an field/item to a key struct */
unknown's avatar
unknown committed
1904 1905 1906

class store_key :public Sql_alloc
{
1907 1908
public:
  bool null_key; /* TRUE <=> the value of the key has a null part */
unknown's avatar
unknown committed
1909
  enum store_key_result { STORE_KEY_OK, STORE_KEY_FATAL, STORE_KEY_CONV };
Igor Babaev's avatar
Igor Babaev committed
1910
  enum Type { FIELD_STORE_KEY, ITEM_STORE_KEY, CONST_ITEM_STORE_KEY };
1911
  store_key(THD *thd, Field *field_arg, uchar *ptr, uchar *null, uint length)
1912
    :null_key(0), null_ptr(null), err(0)
unknown's avatar
unknown committed
1913
  {
1914 1915
    to_field=field_arg->new_key_field(thd->mem_root, field_arg->table,
                                      ptr, length, null, 1);
unknown's avatar
unknown committed
1916
  }
1917
  store_key(store_key &arg)
unknown's avatar
unknown committed
1918
    :Sql_alloc(), null_key(arg.null_key), to_field(arg.to_field),
1919 1920 1921
             null_ptr(arg.null_ptr), err(arg.err)

  {}
unknown's avatar
unknown committed
1922
  virtual ~store_key() {}			/** Not actually needed */
Igor Babaev's avatar
Igor Babaev committed
1923
  virtual enum Type type() const=0;
unknown's avatar
unknown committed
1924
  virtual const char *name() const=0;
Igor Babaev's avatar
Igor Babaev committed
1925
  virtual bool store_key_is_const() { return false; }
1926 1927 1928 1929 1930 1931 1932 1933 1934 1935

  /**
    @brief sets ignore truncation warnings mode and calls the real copy method

    @details this function makes sure truncation warnings when preparing the
    key buffers don't end up as errors (because of an enclosing INSERT/UPDATE).
  */
  enum store_key_result copy()
  {
    enum store_key_result result;
1936
    THD *thd= to_field->table->in_use;
1937 1938
    Check_level_instant_set check_level_save(thd, CHECK_FIELD_IGNORE);
    Sql_mode_save sql_mode(thd);
1939
    thd->variables.sql_mode&= ~(MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE);
1940
    thd->variables.sql_mode|= MODE_INVALID_DATES;
1941 1942 1943 1944 1945 1946
    result= copy_inner();
    return result;
  }

 protected:
  Field *to_field;				// Store data here
1947 1948
  uchar *null_ptr;
  uchar err;
1949 1950

  virtual enum store_key_result copy_inner()=0;
unknown's avatar
unknown committed
1951 1952 1953 1954 1955 1956 1957 1958
};


class store_key_field: public store_key
{
  Copy_field copy_field;
  const char *field_name;
 public:
1959 1960
  store_key_field(THD *thd, Field *to_field_arg, uchar *ptr,
                  uchar *null_ptr_arg,
unknown's avatar
unknown committed
1961
		  uint length, Field *from_field, const char *name_arg)
unknown's avatar
unknown committed
1962
    :store_key(thd, to_field_arg,ptr,
unknown's avatar
unknown committed
1963
	       null_ptr_arg ? null_ptr_arg : from_field->maybe_null() ? &err
1964
	       : (uchar*) 0, length), field_name(name_arg)
unknown's avatar
unknown committed
1965 1966 1967 1968 1969
  {
    if (to_field)
    {
      copy_field.set(to_field,from_field,0);
    }
Igor Babaev's avatar
Igor Babaev committed
1970 1971
  }  

1972 1973
  enum Type type() const override { return FIELD_STORE_KEY; }
  const char *name() const override { return field_name; }
1974

Igor Babaev's avatar
Igor Babaev committed
1975 1976 1977 1978 1979 1980
  void change_source_field(Item_field *fld_item)
  {
    copy_field.set(to_field, fld_item->field, 0);
    field_name= fld_item->full_name();
  }

1981
 protected: 
1982
  enum store_key_result copy_inner() override
1983
  {
1984
    TABLE *table= copy_field.to_field->table;
1985 1986
    MY_BITMAP *old_map= dbug_tmp_use_all_columns(table,
                                                 &table->write_set);
Igor Babaev's avatar
Igor Babaev committed
1987 1988 1989 1990 1991 1992 1993 1994 1995

    /* 
      It looks like the next statement is needed only for a simplified
      hash function over key values used now in BNLH join.
      When the implementation of this function will be replaced for a proper
      full version this statement probably should be removed.
    */  
    bzero(copy_field.to_ptr,copy_field.to_length);

1996
    copy_field.do_copy(&copy_field);
1997
    dbug_tmp_restore_column_map(&table->write_set, old_map);
1998
    null_key= to_field->is_null();
unknown's avatar
unknown committed
1999
    return err != 0 ? STORE_KEY_FATAL : STORE_KEY_OK;
2000
  }
unknown's avatar
unknown committed
2001 2002 2003 2004 2005 2006 2007
};


class store_key_item :public store_key
{
 protected:
  Item *item;
unknown's avatar
unknown committed
2008 2009 2010 2011 2012
  /*
    Flag that forces usage of save_val() method which save value of the
    item instead of save_in_field() method which saves result.
  */
  bool use_value;
unknown's avatar
unknown committed
2013
public:
2014
  store_key_item(THD *thd, Field *to_field_arg, uchar *ptr,
unknown's avatar
unknown committed
2015
                 uchar *null_ptr_arg, uint length, Item *item_arg, bool val)
2016
    :store_key(thd, to_field_arg, ptr,
2017
	       null_ptr_arg ? null_ptr_arg : item_arg->maybe_null() ?
unknown's avatar
unknown committed
2018
	       &err : (uchar*) 0, length), item(item_arg), use_value(val)
unknown's avatar
unknown committed
2019
  {}
2020 2021 2022 2023
  store_key_item(store_key &arg, Item *new_item, bool val)
    :store_key(arg), item(new_item), use_value(val)
  {}

Igor Babaev's avatar
Igor Babaev committed
2024

2025 2026
  enum Type type() const override { return ITEM_STORE_KEY; }
  const char *name() const  override { return "func"; }
2027 2028

 protected:  
2029
  enum store_key_result copy_inner() override
unknown's avatar
unknown committed
2030
  {
2031
    TABLE *table= to_field->table;
2032 2033
    MY_BITMAP *old_map= dbug_tmp_use_all_columns(table,
                                                 &table->write_set);
unknown's avatar
unknown committed
2034
    int res= FALSE;
Igor Babaev's avatar
Igor Babaev committed
2035 2036 2037 2038 2039 2040 2041 2042 2043

    /* 
      It looks like the next statement is needed only for a simplified
      hash function over key values used now in BNLH join.
      When the implementation of this function will be replaced for a proper
      full version this statement probably should be removed.
    */  
    to_field->reset();

unknown's avatar
unknown committed
2044 2045 2046 2047
    if (use_value)
      item->save_val(to_field);
    else
      res= item->save_in_field(to_field, 1);
2048 2049 2050 2051 2052
    /*
     Item::save_in_field() may call Item::val_xxx(). And if this is a subquery
     we need to check for errors executing it and react accordingly
    */
    if (!res && table->in_use->is_error())
2053
      res= 1; /* STORE_KEY_FATAL */
2054
    dbug_tmp_restore_column_map(&table->write_set, old_map);
2055
    null_key= to_field->is_null() || item->null_value;
2056 2057
    return ((err != 0 || res < 0 || res > 2) ? STORE_KEY_FATAL : 
            (store_key_result) res);
unknown's avatar
unknown committed
2058 2059 2060 2061 2062 2063 2064 2065
  }
};


class store_key_const_item :public store_key_item
{
  bool inited;
public:
2066 2067
  store_key_const_item(THD *thd, Field *to_field_arg, uchar *ptr,
		       uchar *null_ptr_arg, uint length,
unknown's avatar
unknown committed
2068
		       Item *item_arg)
2069
    :store_key_item(thd, to_field_arg, ptr,
2070
		    null_ptr_arg ? null_ptr_arg : item_arg->maybe_null() ?
unknown's avatar
unknown committed
2071
		    &err : (uchar*) 0, length, item_arg, FALSE), inited(0)
unknown's avatar
unknown committed
2072 2073
  {
  }
2074 2075 2076
  store_key_const_item(store_key &arg, Item *new_item)
    :store_key_item(arg, new_item, FALSE), inited(0)
  {}
Igor Babaev's avatar
Igor Babaev committed
2077

2078 2079 2080
  enum Type type() const override { return CONST_ITEM_STORE_KEY; }
  const char *name() const  override { return "const"; }
  bool store_key_is_const() override { return true; }
2081 2082

protected:  
2083
  enum store_key_result copy_inner() override
unknown's avatar
unknown committed
2084
  {
unknown's avatar
unknown committed
2085
    int res;
unknown's avatar
unknown committed
2086 2087 2088
    if (!inited)
    {
      inited=1;
2089
      TABLE *table= to_field->table;
2090 2091
      MY_BITMAP *old_map= dbug_tmp_use_all_columns(table,
                                                   &table->write_set);
unknown's avatar
unknown committed
2092 2093 2094
      if ((res= item->save_in_field(to_field, 1)))
      {       
        if (!err)
2095
          err= res < 0 ? 1 : res; /* 1=STORE_KEY_FATAL */
unknown's avatar
unknown committed
2096
      }
2097 2098 2099 2100 2101
      /*
        Item::save_in_field() may call Item::val_xxx(). And if this is a subquery
        we need to check for errors executing it and react accordingly
        */
      if (!err && to_field->table->in_use->is_error())
2102
        err= 1; /* STORE_KEY_FATAL */
2103
      dbug_tmp_restore_column_map(&table->write_set, old_map);
unknown's avatar
unknown committed
2104
    }
2105
    null_key= to_field->is_null() || item->null_value;
2106
    return (err > 2 ? STORE_KEY_FATAL : (store_key_result) err);
unknown's avatar
unknown committed
2107 2108 2109
  }
};

2110 2111 2112 2113 2114
void best_access_path(JOIN *join, JOIN_TAB *s,
                      table_map remaining_tables,
                      const POSITION *join_positions, uint idx,
                      bool disable_jbuf, double record_count,
                      POSITION *pos, POSITION *loose_scan_pos);
2115
bool cp_buffer_from_ref(THD *thd, TABLE *table, TABLE_REF *ref);
unknown's avatar
unknown committed
2116
bool error_if_full_join(JOIN *join);
2117
int report_error(TABLE *table, int error);
2118
int safe_index_read(JOIN_TAB *tab);
2119
int get_quick_record(SQL_SELECT *select);
2120
int setup_order(THD *thd, Ref_ptr_array ref_pointer_array, TABLE_LIST *tables,
2121
                List<Item> &fields, List <Item> &all_fields, ORDER *order,
Igor Babaev's avatar
Igor Babaev committed
2122
                bool from_window_spec= false);
2123
int setup_group(THD *thd,  Ref_ptr_array ref_pointer_array, TABLE_LIST *tables,
2124
		List<Item> &fields, List<Item> &all_fields, ORDER *order,
Igor Babaev's avatar
Igor Babaev committed
2125
		bool *hidden_group_fields, bool from_window_spec= false);
2126
bool fix_inner_refs(THD *thd, List<Item> &all_fields, SELECT_LEX *select,
2127
                    Ref_ptr_array ref_pointer_array);
Sergei Golubchik's avatar
merge.  
Sergei Golubchik committed
2128 2129
int join_read_key2(THD *thd, struct st_join_table *tab, TABLE *table,
                   struct st_table_ref *table_ref);
2130 2131 2132

bool handle_select(THD *thd, LEX *lex, select_result *result,
                   ulong setup_tables_done_option);
2133
bool mysql_select(THD *thd, TABLE_LIST *tables, List<Item> &list,
2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149
                  COND *conds, uint og_num, ORDER *order, ORDER *group,
                  Item *having, ORDER *proc_param, ulonglong select_type, 
                  select_result *result, SELECT_LEX_UNIT *unit, 
                  SELECT_LEX *select_lex);
void free_underlaid_joins(THD *thd, SELECT_LEX *select);
bool mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit,
                         select_result *result);

/*
  General routine to change field->ptr of a NULL-terminated array of Field
  objects. Useful when needed to call val_int, val_str or similar and the
  field data is not in table->record[0] but in some other structure.
  set_key_field_ptr changes all fields of an index using a key_info object.
  All methods presume that there is at least one field to change.
*/

2150 2151 2152 2153

class Virtual_tmp_table: public TABLE
{
  /**
2154
    Destruct collected fields. This method can be called on errors,
2155 2156 2157 2158 2159
    when we could not make the virtual temporary table completely,
    e.g. when some of the fields could not be created or added.

    This is needed to avoid memory leaks, as some fields can be BLOB
    variants and thus can have String onboard. Strings must be destructed
2160
    as they store data on the heap (not on MEM_ROOT).
2161 2162 2163 2164
  */
  void destruct_fields()
  {
    for (uint i= 0; i < s->fields; i++)
2165 2166
    {
      field[i]->free();
2167
      delete field[i];  // to invoke the field destructor
2168
    }
2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194
    s->fields= 0;       // safety
  }

protected:
  /**
     The number of the fields that are going to be in the table.
     We remember the number of the fields at init() time, and
     at open() we check that all of the fields were really added.
  */
  uint m_alloced_field_count;

  /**
    Setup field pointers and null-bit pointers.
  */
  void setup_field_pointers();

public:
  /**
    Create a new empty virtual temporary table on the thread mem_root.
    After creation, the caller must:
    - call init()
    - populate the table with new fields using add().
    - call open().
    @param thd         - Current thread.
  */
  static void *operator new(size_t size, THD *thd) throw();
Marko Mäkelä's avatar
Marko Mäkelä committed
2195
  static void operator delete(void *ptr, size_t size) { TRASH_FREE(ptr, size); }
2196
  static void operator delete(void *, THD *) throw(){}
2197

Sergei Golubchik's avatar
Sergei Golubchik committed
2198
  Virtual_tmp_table(THD *thd) : m_alloced_field_count(0)
2199
  {
Sergei Golubchik's avatar
Sergei Golubchik committed
2200
    reset();
2201 2202
    temp_pool_slot= MY_BIT_NONE;
    in_use= thd;
2203 2204
    copy_blobs= true;
    alias.set("", 0, &my_charset_bin);
2205 2206 2207 2208
  }

  ~Virtual_tmp_table()
  {
2209 2210
    if (s)
      destruct_fields();
2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233
  }

  /**
    Allocate components for the given number of fields.
     - fields[]
     - s->blob_fields[],
     - bitmaps: def_read_set, def_write_set, tmp_set, eq_join_set, cond_set.
    @param field_count - The number of fields we plan to add to the table.
    @returns false     - on success.
    @returns true      - on error.
  */
  bool init(uint field_count);

  /**
    Add one Field to the end of the field array, update members:
    s->reclength, s->fields, s->blob_fields, s->null_fuelds.
  */
  bool add(Field *new_field)
  {
    DBUG_ASSERT(s->fields < m_alloced_field_count);
    new_field->init(this);
    field[s->fields]= new_field;
    s->reclength+= new_field->pack_length();
2234
    if (!(new_field->flags & NOT_NULL_FLAG))
2235
      s->null_fields++;
2236
    if (new_field->flags & BLOB_FLAG)
2237 2238 2239 2240 2241 2242
    {
      // Note, s->blob_fields was incremented in Field_blob::Field_blob
      DBUG_ASSERT(s->blob_fields);
      DBUG_ASSERT(s->blob_fields <= m_alloced_field_count);
      s->blob_field[s->blob_fields - 1]= s->fields;
    }
2243
    new_field->field_index= s->fields++;
2244 2245 2246 2247
    return false;
  }

  /**
2248
    Add fields from a Spvar_definition list
2249 2250 2251
    @returns false - on success.
    @returns true  - on error.
  */
2252
  bool add(List<Spvar_definition> &field_list);
2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265

  /**
    Open a virtual table for read/write:
    - Setup end markers in TABLE::field and TABLE_SHARE::blob_fields,
    - Allocate a buffer in TABLE::record[0].
    - Set field pointers (Field::ptr, Field::null_pos, Field::null_bit) to
      the allocated record.
    This method is called when all of the fields have been added to the table.
    After calling this method the table is ready for read and write operations.
    @return false - on success
    @return true  - on error (e.g. could not allocate the record buffer).
  */
  bool open();
2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307

  void set_all_fields_to_null()
  {
    for (uint i= 0; i < s->fields; i++)
      field[i]->set_null();
  }
  /**
    Set all fields from a compatible item list.
    The number of fields in "this" must be equal to the number
    of elements in "value".
  */
  bool sp_set_all_fields_from_item_list(THD *thd, List<Item> &items);

  /**
    Set all fields from a compatible item.
    The number of fields in "this" must be the same with the number
    of elements in "value".
  */
  bool sp_set_all_fields_from_item(THD *thd, Item *value);

  /**
    Find a ROW element index by its name
    Assumes that "this" is used as a storage for a ROW-type SP variable.
    @param [OUT] idx        - the index of the found field is returned here
    @param [IN]  field_name - find a field with this name
    @return      true       - on error (the field was not found)
    @return      false      - on success (idx[0] was set to the field index)
  */
  bool sp_find_field_by_name(uint *idx, const LEX_CSTRING &name) const;

  /**
    Find a ROW element index by its name.
    If the element is not found, and error is issued.
    @param [OUT] idx        - the index of the found field is returned here
    @param [IN]  var_name   - the name of the ROW variable (for error reporting)
    @param [IN]  field_name - find a field with this name
    @return      true       - on error (the field was not found)
    @return      false      - on success (idx[0] was set to the field index)
  */
  bool sp_find_field_by_name_or_error(uint *idx,
                                      const LEX_CSTRING &var_name,
                                      const LEX_CSTRING &field_name) const;
2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330
};


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

    The created table doesn't have a table handler associated 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.

  @param thd         connection handle
  @param field_list  list of column definitions

  @return
    0 if out of memory, or a
    TABLE object ready for read and write in case of success
*/

2331
inline Virtual_tmp_table *
2332
create_virtual_tmp_table(THD *thd, List<Spvar_definition> &field_list)
2333 2334 2335 2336
{
  Virtual_tmp_table *table;
  if (!(table= new(thd) Virtual_tmp_table(thd)))
    return NULL;
2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347

  /*
    If "simulate_create_virtual_tmp_table_out_of_memory" debug option
    is enabled, we now enable "simulate_out_of_memory". This effectively
    makes table->init() fail on OOM inside multi_alloc_root().
    This is done to test that ~Virtual_tmp_table() called from the "delete"
    below correcly handles OOM.
  */
  DBUG_EXECUTE_IF("simulate_create_virtual_tmp_table_out_of_memory",
                  DBUG_SET("+d,simulate_out_of_memory"););

2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384
  if (table->init(field_list.elements) ||
      table->add(field_list) ||
      table->open())
  {
    delete table;
    return NULL;
  }
  return table;
}


/**
  Create a new virtual temporary table consisting of a single field.
  SUM(DISTINCT expr) and similar numeric aggregate functions use this.
  @param thd    - Current thread
  @param field  - The field that will be added into the table.
  @return NULL  - On error.
  @return !NULL - A pointer to the created table that is ready
                  for read and write.
*/
inline TABLE *
create_virtual_tmp_table(THD *thd, Field *field)
{
  Virtual_tmp_table *table;
  DBUG_ASSERT(field);
  if (!(table= new(thd) Virtual_tmp_table(thd)))
    return NULL;
  if (table->init(1) ||
      table->add(field) ||
      table->open())
  {
    delete table;
    return NULL;
  }
  return table;
}

2385

2386
int test_if_item_cache_changed(List<Cached_item> &list);
2387
int join_init_read_record(JOIN_TAB *tab);
Sergey Petrunia's avatar
Sergey Petrunia committed
2388
void set_position(JOIN *join,uint idx,JOIN_TAB *table,KEYUSE *key);
2389
inline Item * and_items(THD *thd, Item* cond, Item *item)
2390
{
Monty's avatar
Monty committed
2391
  return (cond ? (new (thd->mem_root) Item_cond_and(thd, cond, item)) : item);
2392
}
2393 2394 2395 2396
inline Item * or_items(THD *thd, Item* cond, Item *item)
{
  return (cond ? (new (thd->mem_root) Item_cond_or(thd, cond, item)) : item);
}
unknown's avatar
MWL#89  
unknown committed
2397
bool choose_plan(JOIN *join, table_map join_tables);
2398 2399 2400
void optimize_wo_join_buffering(JOIN *join, uint first_tab, uint last_tab, 
                                table_map last_remaining_tables, 
                                bool first_alt, uint no_jbuf_before,
2401
                                double *outer_rec_count, double *reopt_cost);
2402 2403
Item_equal *find_item_equal(COND_EQUAL *cond_equal, Field *field,
                            bool *inherited_fl);
2404
extern bool test_if_ref(Item *, 
2405
                 Item_field *left_item,Item *right_item);
2406

2407
inline bool optimizer_flag(THD *thd, ulonglong flag)
2408 2409 2410 2411
{ 
  return (thd->variables.optimizer_switch & flag);
}

2412
/*
Sergey Petrunya's avatar
Sergey Petrunya committed
2413 2414
int print_fake_select_lex_join(select_result_sink *result, bool on_the_fly,
                               SELECT_LEX *select_lex, uint8 select_options);
2415
*/
Sergey Petrunya's avatar
Sergey Petrunya committed
2416

2417
uint get_index_for_order(ORDER *order, TABLE *table, SQL_SELECT *select,
2418 2419
                         ha_rows limit, ha_rows *scanned_limit, 
                         bool *need_sort, bool *reverse);
2420 2421 2422 2423
ORDER *simple_remove_const(ORDER *order, COND *where);
bool const_expression_in_where(COND *cond, Item *comp_item,
                               Field *comp_field= NULL,
                               Item **const_item= NULL);
2424
bool cond_is_datetime_is_null(Item *cond);
2425
bool cond_has_datetime_is_null(Item *cond);
2426

2427
/* Table elimination entry point function */
Sergey Petrunya's avatar
Sergey Petrunya committed
2428
void eliminate_tables(JOIN *join);
Sergey Petrunia's avatar
Sergey Petrunia committed
2429

2430
/* Index Condition Pushdown entry point function */
2431
void push_index_cond(JOIN_TAB *tab, uint keyno);
2432

Igor Babaev's avatar
Igor Babaev committed
2433 2434
#define OPT_LINK_EQUAL_FIELDS    1

Sergey Petrunya's avatar
Sergey Petrunya committed
2435 2436
/* EXPLAIN-related utility functions */
int print_explain_message_line(select_result_sink *result, 
Sergei Petrunia's avatar
Sergei Petrunia committed
2437
                               uint8 options, bool is_analyze,
Sergey Petrunya's avatar
Sergey Petrunya committed
2438 2439
                               uint select_number,
                               const char *select_type,
2440
                               ha_rows *rows,
Sergey Petrunya's avatar
Sergey Petrunya committed
2441 2442
                               const char *message);
void explain_append_mrr_info(QUICK_RANGE_SELECT *quick, String *res);
2443 2444
int append_possible_keys(MEM_ROOT *alloc, String_list &list, TABLE *table, 
                         key_map possible_keys);
2445
void unpack_to_base_table_fields(TABLE *table);
Sergey Petrunya's avatar
Sergey Petrunya committed
2446

2447 2448 2449 2450 2451 2452 2453 2454 2455
/****************************************************************************
  Temporary table support for SQL Runtime
 ***************************************************************************/

#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

2456
void calc_group_buffer(TMP_TABLE_PARAM *param, ORDER *group);
2457 2458 2459
TABLE *create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
			ORDER *group, bool distinct, bool save_sum_fields,
			ulonglong select_options, ha_rows rows_limit,
2460
                        const LEX_CSTRING *alias, bool do_not_open=FALSE,
2461
                        bool keep_row_order= FALSE);
2462 2463 2464 2465
TABLE *create_tmp_table_for_schema(THD *thd, TMP_TABLE_PARAM *param,
                                   const ST_SCHEMA_TABLE &schema_table,
                                   longlong select_options,
                                   const LEX_CSTRING &alias,
Marko Mäkelä's avatar
Marko Mäkelä committed
2466
                                   bool do_not_open, bool keep_row_order);
2467

2468 2469
void free_tmp_table(THD *thd, TABLE *entry);
bool create_internal_tmp_table_from_heap(THD *thd, TABLE *table,
Sergei Golubchik's avatar
Sergei Golubchik committed
2470 2471
                                         TMP_ENGINE_COLUMNDEF *start_recinfo,
                                         TMP_ENGINE_COLUMNDEF **recinfo, 
2472 2473
                                         int error, bool ignore_last_dupp_key_error,
                                         bool *is_duplicate);
2474
bool create_internal_tmp_table(TABLE *table, KEY *keyinfo, 
Sergei Golubchik's avatar
Sergei Golubchik committed
2475 2476
                               TMP_ENGINE_COLUMNDEF *start_recinfo,
                               TMP_ENGINE_COLUMNDEF **recinfo, 
2477
                               ulonglong options);
Igor Babaev's avatar
Igor Babaev committed
2478
bool instantiate_tmp_table(TABLE *table, KEY *keyinfo, 
2479 2480
                           TMP_ENGINE_COLUMNDEF *start_recinfo,
                           TMP_ENGINE_COLUMNDEF **recinfo,
Igor Babaev's avatar
Igor Babaev committed
2481
                           ulonglong options);
2482
bool open_tmp_table(TABLE *table);
2483
double prev_record_reads(const POSITION *positions, uint idx, table_map found_ref);
2484
void fix_list_after_tbl_changes(SELECT_LEX *new_parent, List<TABLE_LIST> *tlist);
2485 2486 2487 2488 2489
double get_tmp_table_lookup_cost(THD *thd, double row_count, uint row_size);
double get_tmp_table_write_cost(THD *thd, double row_count, uint row_size);
void optimize_keyuse(JOIN *join, DYNAMIC_ARRAY *keyuse_array);
bool sort_and_filter_keyuse(THD *thd, DYNAMIC_ARRAY *keyuse,
                            bool skip_unprefixed_keyparts);
2490

unknown's avatar
unknown committed
2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503
struct st_cond_statistic
{
  Item *cond;
  Field *field_arg;
  ulong positive;
};
typedef struct st_cond_statistic COND_STATISTIC;

ulong check_selectivity(THD *thd,
                        ulong rows_to_read,
                        TABLE *table,
                        List<COND_STATISTIC> *conds);

2504 2505 2506 2507 2508 2509
class Pushdown_query: public Sql_alloc
{
public:
  SELECT_LEX *select_lex;
  bool store_data_in_temp_table;
  group_by_handler *handler;
2510
  Item *having;
2511 2512 2513

  Pushdown_query(SELECT_LEX *select_lex_arg, group_by_handler *handler_arg)
    : select_lex(select_lex_arg), store_data_in_temp_table(0),
2514
    handler(handler_arg), having(0) {}
2515 2516 2517 2518

  ~Pushdown_query() { delete handler; }

  /* Function that calls the above scan functions */
2519
  int execute(JOIN *);
2520
};
Sergei Petrunia's avatar
Sergei Petrunia committed
2521

2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542
class derived_handler;

class Pushdown_derived: public Sql_alloc
{
private:
  bool is_analyze;
public:
  TABLE_LIST *derived;
  derived_handler *handler;

  Pushdown_derived(TABLE_LIST *tbl, derived_handler *h);

  ~Pushdown_derived();

  int execute(); 
};


class select_handler;


2543 2544 2545
bool test_if_order_compatible(SQL_I_List<ORDER> &a, SQL_I_List<ORDER> &b);
int test_if_group_changed(List<Cached_item> &list);
int create_sort_index(THD *thd, JOIN *join, JOIN_TAB *tab, Filesort *fsort);
2546 2547 2548 2549

JOIN_TAB *first_explain_order_tab(JOIN* join);
JOIN_TAB *next_explain_order_tab(JOIN* join, JOIN_TAB* tab);

2550 2551 2552 2553 2554 2555 2556 2557 2558
bool check_simple_equality(THD *thd, const Item::Context &ctx,
                           Item *left_item, Item *right_item,
                           COND_EQUAL *cond_equal);

void propagate_new_equalities(THD *thd, Item *cond,
                              List<Item_equal> *new_equalities,
                              COND_EQUAL *inherited,
                              bool *is_simplifiable_cond);

2559
#endif /* SQL_SELECT_INCLUDED */