00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <config.h>
00022 #include <drizzled/join_table.h>
00023 #include <drizzled/table.h>
00024 #include <drizzled/sql_select.h>
00025 #include <drizzled/internal/my_sys.h>
00026 #include <drizzled/optimizer/access_method/scan.h>
00027 #include <drizzled/util/test.h>
00028 #include <drizzled/statistics_variables.h>
00029 #include <drizzled/session.h>
00030
00031 using namespace drizzled;
00032
00033 static uint32_t make_join_orderinfo(Join *join);
00034
00035 void optimizer::Scan::getStats(Table& table, JoinTable& join_tab)
00036 {
00037 Join *join= join_tab.join;
00038 bool statistics= test(! (join->select_options & SELECT_DESCRIBE));
00039 uint64_t options= (join->select_options &
00040 (SELECT_DESCRIBE | SELECT_NO_JOIN_CACHE)) |
00041 (0);
00042 uint32_t no_jbuf_after= make_join_orderinfo(join);
00043 uint32_t index= &join_tab - join->join_tab;
00044
00045
00046
00047
00048
00049 table.status= STATUS_NO_RECORD;
00050
00051 if (index != join->const_tables &&
00052 ! (options & SELECT_NO_JOIN_CACHE) &&
00053 join_tab.use_quick != 2 &&
00054 ! join_tab.first_inner &&
00055 index <= no_jbuf_after &&
00056 ! join_tab.insideout_match_tab)
00057 {
00058 if ((options & SELECT_DESCRIBE) ||
00059 ! join_init_cache(join->session,
00060 join->join_tab + join->const_tables,
00061 index - join->const_tables))
00062 {
00063 (&join_tab)[-1].next_select= sub_select_cache;
00064 }
00065 }
00066
00067
00068 if (join_tab.use_quick == 2)
00069 {
00070 join->session->server_status|= SERVER_QUERY_NO_GOOD_INDEX_USED;
00071 join_tab.read_first_record= join_init_quick_read_record;
00072 if (statistics)
00073 {
00074 join->session->status_var.select_range_check_count++;
00075 }
00076 }
00077 else
00078 {
00079 join_tab.read_first_record= join_init_read_record;
00080 if (index == join->const_tables)
00081 {
00082 if (join_tab.select && join_tab.select->quick)
00083 {
00084 if (statistics)
00085 join->session->status_var.select_range_count++;
00086 }
00087 else
00088 {
00089 join->session->server_status|= SERVER_QUERY_NO_INDEX_USED;
00090 if (statistics)
00091 join->session->status_var.select_scan_count++;
00092 }
00093 }
00094 else
00095 {
00096 if (join_tab.select && join_tab.select->quick)
00097 {
00098 if (statistics)
00099 join->session->status_var.select_full_range_join_count++;
00100 }
00101 else
00102 {
00103 join->session->server_status|= SERVER_QUERY_NO_INDEX_USED;
00104 if (statistics)
00105 join->session->status_var.select_full_join_count++;
00106 }
00107 }
00108 if (! table.no_keyread)
00109 {
00110 if (join_tab.select &&
00111 join_tab.select->quick &&
00112 join_tab.select->quick->index != MAX_KEY &&
00113 table.covering_keys.test(join_tab.select->quick->index))
00114 {
00115 table.key_read= 1;
00116 table.cursor->extra(HA_EXTRA_KEYREAD);
00117 }
00118 else if (! table.covering_keys.none() && ! (join_tab.select && join_tab.select->quick))
00119 {
00120 if (! join_tab.insideout_match_tab)
00121 {
00122
00123
00124
00125
00126 if (table.getShare()->hasPrimaryKey() &&
00127 table.cursor->primary_key_is_clustered())
00128 {
00129 join_tab.index= table.getShare()->getPrimaryKey();
00130 }
00131 else
00132 {
00133 join_tab.index= table.find_shortest_key(&table.covering_keys);
00134 }
00135 }
00136 join_tab.read_first_record= join_read_first;
00137 join_tab.type= AM_NEXT;
00138 }
00139 }
00140 }
00141 }
00142
00152 static uint32_t make_join_orderinfo(Join *join)
00153 {
00154 if (join->need_tmp)
00155 return join->tables;
00156
00157 uint32_t i= join->const_tables;
00158 for (; i < join->tables; i++)
00159 {
00160 JoinTable *tab= join->join_tab + i;
00161 Table *table= tab->table;
00162 if ((table == join->sort_by_table &&
00163 (! join->order || join->skip_sort_order)) ||
00164 (join->sort_by_table == (Table *) 1 && i != join->const_tables))
00165 {
00166 break;
00167 }
00168 }
00169 return i;
00170 }