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/session.h>
00023 #include <drizzled/join_table.h>
00024 #include <drizzled/table.h>
00025 #include <drizzled/sql_select.h>
00026 #include <drizzled/internal/my_sys.h>
00027 #include <drizzled/optimizer/access_method/scan.h>
00028
00029 using namespace drizzled;
00030
00031 static uint32_t make_join_orderinfo(Join *join);
00032
00033 bool optimizer::Scan::getStats(Table *table,
00034 JoinTable *join_tab)
00035 {
00036 Join *join= join_tab->join;
00037 bool statistics= test(! (join->select_options & SELECT_DESCRIBE));
00038 uint64_t options= (join->select_options &
00039 (SELECT_DESCRIBE | SELECT_NO_JOIN_CACHE)) |
00040 (0);
00041 uint32_t no_jbuf_after= make_join_orderinfo(join);
00042 uint32_t index= join_tab - join->join_tab;
00043
00044
00045
00046
00047
00048 table->status= STATUS_NO_RECORD;
00049
00050 if (index != join->const_tables &&
00051 ! (options & SELECT_NO_JOIN_CACHE) &&
00052 join_tab->use_quick != 2 &&
00053 ! join_tab->first_inner &&
00054 index <= no_jbuf_after &&
00055 ! join_tab->insideout_match_tab)
00056 {
00057 if ((options & SELECT_DESCRIBE) ||
00058 ! join_init_cache(join->session,
00059 join->join_tab + join->const_tables,
00060 index - join->const_tables))
00061 {
00062 join_tab[-1].next_select= sub_select_cache;
00063 }
00064 }
00065
00066
00067 if (join_tab->use_quick == 2)
00068 {
00069 join->session->server_status|= SERVER_QUERY_NO_GOOD_INDEX_USED;
00070 join_tab->read_first_record= join_init_quick_read_record;
00071 if (statistics)
00072 {
00073 join->session->status_var.select_range_check_count++;
00074 }
00075 }
00076 else
00077 {
00078 join_tab->read_first_record= join_init_read_record;
00079 if (index == join->const_tables)
00080 {
00081 if (join_tab->select && join_tab->select->quick)
00082 {
00083 if (statistics)
00084 {
00085 join->session->status_var.select_range_count++;
00086 }
00087 }
00088 else
00089 {
00090 join->session->server_status|= SERVER_QUERY_NO_INDEX_USED;
00091 if (statistics)
00092 {
00093 join->session->status_var.select_scan_count++;
00094 }
00095 }
00096 }
00097 else
00098 {
00099 if (join_tab->select && join_tab->select->quick)
00100 {
00101 if (statistics)
00102 {
00103 join->session->status_var.select_full_range_join_count++;
00104 }
00105 }
00106 else
00107 {
00108 join->session->server_status|= SERVER_QUERY_NO_INDEX_USED;
00109 if (statistics)
00110 {
00111 join->session->status_var.select_full_join_count++;
00112 }
00113 }
00114 }
00115 if (! table->no_keyread)
00116 {
00117 if (join_tab->select &&
00118 join_tab->select->quick &&
00119 join_tab->select->quick->index != MAX_KEY &&
00120 table->covering_keys.test(join_tab->select->quick->index))
00121 {
00122 table->key_read= 1;
00123 table->cursor->extra(HA_EXTRA_KEYREAD);
00124 }
00125 else if (! table->covering_keys.none() &&
00126 ! (join_tab->select && join_tab->select->quick))
00127 {
00128 if (! join_tab->insideout_match_tab)
00129 {
00130
00131
00132
00133
00134 if (table->getShare()->hasPrimaryKey() &&
00135 table->cursor->primary_key_is_clustered())
00136 {
00137 join_tab->index= table->getShare()->getPrimaryKey();
00138 }
00139 else
00140 {
00141 join_tab->index= table->find_shortest_key(&table->covering_keys);
00142 }
00143 }
00144 join_tab->read_first_record= join_read_first;
00145 join_tab->type= AM_NEXT;
00146 }
00147 }
00148 }
00149
00150 return false;
00151 }
00152
00162 static uint32_t make_join_orderinfo(Join *join)
00163 {
00164 uint32_t i= 0;
00165 if (join->need_tmp)
00166 {
00167 return join->tables;
00168 }
00169
00170 for (i= join->const_tables ; i < join->tables ; i++)
00171 {
00172 JoinTable *tab= join->join_tab + i;
00173 Table *table= tab->table;
00174 if ((table == join->sort_by_table &&
00175 (! join->order || join->skip_sort_order)) ||
00176 (join->sort_by_table == (Table *) 1 && i != join->const_tables))
00177 {
00178 break;
00179 }
00180 }
00181 return i;
00182 }