zoukankan      html  css  js  c++  java
  • class JOIN

    class JOIN :public Sql_alloc
    {
      JOIN(const JOIN &rhs);                        /**< not implemented */
      JOIN& operator=(const JOIN &rhs);             /**< not implemented */
    public:
      JOIN_TAB *join_tab,**best_ref;
      JOIN_TAB **map2table;    ///< mapping between table indexes and JOIN_TABs
      JOIN_TAB *join_tab_save; ///< saved join_tab for subquery reexecution
      TABLE    **all_tables,*sort_by_table;
      uint       tables,const_tables;
      uint       send_group_parts;
      /**
        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; 
      bool     first_record,full_join,group, no_field_update;
      bool       do_send_rows;
      table_map const_table_map,found_const_table_map;
      /*
         Bitmap of all inner tables from outer joins
      */
      table_map outer_join;
      ha_rows  send_records,found_records,examined_rows,row_limit, select_limit;
      /**
        Used to fetch no more than given amount of rows per one
        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
      */
      ha_rows  fetch_limit;
      POSITION positions[MAX_TABLES+1],best_positions[MAX_TABLES+1];
      
      /* *
        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;
    
      double   best_read;
      List<Item> *fields;
      List<Cached_item> group_fields, group_fields_cache;
      TABLE    *tmp_table;
      /// used to store 2 possible tmp table of SELECT
      TABLE    *exec_tmp_table1, *exec_tmp_table2;
      THD       *thd;
      Item_sum  **sum_funcs, ***sum_funcs_end;
      /** second copy of sumfuncs (for queries with 2 temporary tables */
      Item_sum  **sum_funcs2, ***sum_funcs_end2;
      Procedure *procedure;
      Item        *having;
      Item      *tmp_having; ///< To store having when processed temporary table
      Item      *having_history; ///< Store having for explain
      ulonglong  select_options;
      select_result *result;
      TMP_TABLE_PARAM tmp_table_param;
      MYSQL_LOCK *lock;
      /// unit structure (with global parameters) for this select
      SELECT_LEX_UNIT *unit;
      /// select that processed
      SELECT_LEX *select_lex;
      /** 
        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; 
      
      /**
        Copy of this JOIN to be used with temporary tables.
    
        tmp_join is used when the JOIN needs to be "reusable" (e.g. in a subquery
        that gets re-executed several times) and we know will use temporary tables
        for materialization. The materialization to a temporary table overwrites the
        JOIN structure to point to the temporary table after the materialization is
        done. This is where tmp_join is used : it's a copy of the JOIN before the
        materialization and is used in restoring before re-execution by overwriting
        the current JOIN structure with the saved copy.
        Because of this we should pay extra care of not freeing up helper structures
        that are referenced by the original contents of the JOIN. We can check for
        this by making sure the "current" join is not the temporary copy, e.g.
        !tmp_join || tmp_join != join
     
        We should free these sub-structures at JOIN::destroy() if the "current" join
        has a copy is not that copy.
      */
      JOIN *tmp_join;
      ROLLUP rollup;                ///< Used with rollup
    
      bool select_distinct;                ///< Set if SELECT DISTINCT
      /**
        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;
    
      /*
        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.
        Used for deciding for or against using a temporary table to compute 
        GROUP/ORDER BY.
      */
      bool simple_order, simple_group;
      /**
        Is set only in case if we have a GROUP BY clause
        and no ORDER BY after constant elimination of 'order'.
      */
      bool no_order;
      /** Is set if we have a GROUP BY and we have ORDER BY on a constant. */
      bool          skip_sort_order;
    
      bool need_tmp, hidden_group_fields;
      DYNAMIC_ARRAY keyuse;
      Item::cond_result cond_value, having_value;
      List<Item> all_fields; ///< to store all fields that used in query
      ///Above list changed to use temporary table
      List<Item> tmp_all_fields1, tmp_all_fields2, tmp_all_fields3;
      ///Part, shared with list above, emulate following list
      List<Item> tmp_fields_list1, tmp_fields_list2, tmp_fields_list3;
      List<Item> &fields_list; ///< hold field list passed to mysql_select
      List<Item> procedure_fields_list;
      int error;
    
      ORDER *order, *group_list, *proc_param; //hold parameters of mysql_select
      COND *conds;                            // ---"---
      Item *conds_history;                    // store WHERE for explain
      TABLE_LIST *tables_list;           ///<hold 'tables' parameter of mysql_select
      List<TABLE_LIST> *join_list;       ///< list of joined tables in reverse order
      COND_EQUAL *cond_equal;
      SQL_SELECT *select;                ///<created in optimisation phase
      JOIN_TAB *return_tab;              ///<used only for outer joins
      Item **ref_pointer_array; ///<used pointer reference for this select
      // Copy of above to be used with different lists
      Item **items0, **items1, **items2, **items3, **current_ref_pointer_array;
      uint ref_pointer_array_size; ///< size of above in bytes
      const char *zero_result_cause; ///< not 0 if exec must return zero result
      
      bool union_part; ///< this subselect is part of union 
      bool optimized; ///< flag to avoid double optimization in EXPLAIN
    
      /* 
        storage for caching buffers allocated during query execution. 
        These buffers allocations need to be cached as the thread memory pool is
        cleared only at the end of the execution of the whole query and not caching
        allocations that occur in repetition at execution time will result in 
        excessive memory usage.
        Note: make_simple_join always creates an execution plan that accesses
        a single table, thus it is sufficient to have a one-element array for
        table_reexec.
      */  
      SORT_FIELD *sortorder;                        // make_unireg_sortorder()
      TABLE *table_reexec[1];                       // make_simple_join()
      JOIN_TAB *join_tab_reexec;                    // make_simple_join()
      /* end of allocation caching storage */
    
      JOIN(THD *thd_arg, List<Item> &fields_arg, ulonglong select_options_arg,
           select_result *result_arg)
        :fields_list(fields_arg)
      {
        init(thd_arg, fields_arg, select_options_arg, result_arg);
      }
    
      void init(THD *thd_arg, List<Item> &fields_arg, ulonglong select_options_arg,
           select_result *result_arg)
      {
        join_tab= join_tab_save= 0;
        all_tables= 0;
        tables= 0;
        const_tables= 0;
        join_list= 0;
        implicit_grouping= FALSE;
        sort_and_group= 0;
        first_record= 0;
        do_send_rows= 1;
        send_records= 0;
        found_records= 0;
        fetch_limit= HA_POS_ERROR;
        examined_rows= 0;
        exec_tmp_table1= 0;
        exec_tmp_table2= 0;
        sortorder= 0;
        table_reexec[0]= 0;
        join_tab_reexec= 0;
        thd= thd_arg;
        sum_funcs= sum_funcs2= 0;
        procedure= 0;
        having= tmp_having= having_history= 0;
        select_options= select_options_arg;
        result= result_arg;
        lock= thd_arg->lock;
        select_lex= 0; //for safety
        tmp_join= 0;
        select_distinct= test(select_options & SELECT_DISTINCT);
        no_order= 0;
        simple_order= 0;
        simple_group= 0;
        skip_sort_order= 0;
        need_tmp= 0;
        hidden_group_fields= 0; /*safety*/
        error= 0;
        select= 0;
        return_tab= 0;
        ref_pointer_array= items0= items1= items2= items3= 0;
        ref_pointer_array_size= 0;
        zero_result_cause= 0;
        optimized= 0;
        cond_equal= 0;
        group_optimized_away= 0;
    
        all_fields= fields_arg;
        if (&fields_list != &fields_arg)      /* Avoid valgrind-warning */
          fields_list= fields_arg;
        bzero((char*) &keyuse,sizeof(keyuse));
        tmp_table_param.init();
        tmp_table_param.end_write_records= HA_POS_ERROR;
        rollup.state= ROLLUP::STATE_NONE;
    
        no_const_tables= FALSE;
      }
    
      int prepare(Item ***rref_pointer_array, TABLE_LIST *tables, uint wind_num,
              COND *conds, uint og_num, ORDER *order, ORDER *group,
              Item *having, ORDER *proc_param, SELECT_LEX *select,
              SELECT_LEX_UNIT *unit);
      int optimize();
      int reinit();
      void exec();
      int destroy();
      void restore_tmp();
      bool alloc_func_list();
      bool make_sum_func_list(List<Item> &all_fields, List<Item> &send_fields,
                  bool before_group_by, bool recompute= FALSE);
    
      inline void set_items_ref_array(Item **ptr)
      {
        memcpy((char*) ref_pointer_array, (char*) ptr, ref_pointer_array_size);
        current_ref_pointer_array= ptr;
      }
      inline void init_items_ref_array()
      {
        items0= ref_pointer_array + all_fields.elements;
        memcpy(items0, ref_pointer_array, ref_pointer_array_size);
        current_ref_pointer_array= items0;
      }
    
      bool rollup_init();
      bool rollup_process_const_fields();
      bool rollup_make_fields(List<Item> &all_fields, List<Item> &fields,
                  Item_sum ***func);
      int rollup_send_data(uint idx);
      int rollup_write_data(uint idx, TABLE *table);
      void remove_subq_pushed_predicates(Item **where);
      /**
        Release memory and, if possible, the open tables held by this execution
        plan (and nested plans). It's used to release some tables before
        the end of execution in order to increase concurrency and reduce
        memory consumption.
      */
      void join_free();
      /** Cleanup this JOIN, possibly for reuse */
      void cleanup(bool full);
      void clear();
      bool save_join_tab();
      bool init_save_join_tab();
      bool send_row_on_empty_set()
      {
        return (do_send_rows && tmp_table_param.sum_func_count != 0 &&
            !group_list && having_value != Item::COND_FALSE);
      }
      bool change_result(select_result *result);
      bool is_top_level_join() const
      {
        return (unit == &thd->lex->unit && (unit->fake_select_lex == 0 ||
                                            select_lex == unit->fake_select_lex));
      }
      void cache_const_exprs();
    private:
      /**
        TRUE if the query contains an aggregate function but has no GROUP
        BY clause. 
      */
      bool implicit_grouping; 
      bool make_simple_join(JOIN *join, TABLE *tmp_table);
      void cleanup_item_list(List<Item> &items) const;
    };
  • 相关阅读:
    HDU 1312 Red and Black DFS(深度优先搜索) 和 BFS(广度优先搜索)
    HDU 1241 Oil Deposits DFS(深度优先搜索) 和 BFS(广度优先搜索)
    邮件推广工具
    aix-syslog
    能量点
    知识picture
    C中运算符
    stdio.h头文件中申明的基本函数
    字符串
    指针字符串
  • 原文地址:https://www.cnblogs.com/taek/p/5088394.html
Copyright © 2011-2022 走看看