00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include <config.h>
00017
00018 #include <string>
00019
00020 #include <drizzled/error.h>
00021 #include <drizzled/table_list.h>
00022 #include <drizzled/item.h>
00023 #include <drizzled/item/field.h>
00024 #include <drizzled/nested_join.h>
00025 #include <drizzled/sql_lex.h>
00026 #include <drizzled/sql_select.h>
00027
00028 using namespace std;
00029
00030 namespace drizzled {
00031
00032 void TableList::set_insert_values()
00033 {
00034 if (table)
00035 {
00036 table->insert_values.resize(table->getShare()->rec_buff_length);
00037 }
00038 }
00039
00040 bool TableList::is_leaf_for_name_resolution() const
00041 {
00042 return is_natural_join || is_join_columns_complete || not nested_join;
00043 }
00044
00045 TableList *TableList::find_underlying_table(Table *table_to_find)
00046 {
00047
00048 if (table == table_to_find)
00049 return this;
00050
00051 return NULL;
00052 }
00053
00054 bool TableList::isCartesian() const
00055 {
00056 return false;
00057 }
00058
00059 bool TableList::placeholder()
00060 {
00061 return derived || (create && !table->getDBStat()) || !table;
00062 }
00063
00064
00065
00066
00067
00068
00069 TableList *TableList::last_leaf_for_name_resolution()
00070 {
00071 TableList *cur_table_ref= this;
00072 NestedJoin *cur_nested_join;
00073
00074 if (is_leaf_for_name_resolution())
00075 return this;
00076 assert(nested_join);
00077
00078 for (cur_nested_join= nested_join;
00079 cur_nested_join;
00080 cur_nested_join= cur_table_ref->nested_join)
00081 {
00082 cur_table_ref= &cur_nested_join->join_list.front();
00083
00084
00085
00086
00087
00088 if ((cur_table_ref->outer_join & JOIN_TYPE_RIGHT))
00089 {
00090 List<TableList>::iterator it(cur_nested_join->join_list.begin());
00091 TableList *next;
00092 cur_table_ref= it++;
00093 while ((next= it++))
00094 cur_table_ref= next;
00095 }
00096 if (cur_table_ref->is_leaf_for_name_resolution())
00097 break;
00098 }
00099 return cur_table_ref;
00100 }
00101
00102
00103
00104
00105
00106
00107 TableList *TableList::first_leaf_for_name_resolution()
00108 {
00109 TableList *cur_table_ref= NULL;
00110 NestedJoin *cur_nested_join;
00111
00112 if (is_leaf_for_name_resolution())
00113 return this;
00114 assert(nested_join);
00115
00116 for (cur_nested_join= nested_join;
00117 cur_nested_join;
00118 cur_nested_join= cur_table_ref->nested_join)
00119 {
00120 List<TableList>::iterator it(cur_nested_join->join_list.begin());
00121 cur_table_ref= it++;
00122
00123
00124
00125
00126
00127
00128 if (!(cur_table_ref->outer_join & JOIN_TYPE_RIGHT))
00129 {
00130 TableList *next;
00131 while ((next= it++))
00132 cur_table_ref= next;
00133 }
00134 if (cur_table_ref->is_leaf_for_name_resolution())
00135 break;
00136 }
00137 return cur_table_ref;
00138 }
00139
00140 Item_subselect *TableList::containing_subselect()
00141 {
00142 return (select_lex ? select_lex->master_unit()->item : 0);
00143 }
00144
00145 bool TableList::process_index_hints(Table *tbl)
00146 {
00147
00148 tbl->keys_in_use_for_query= tbl->keys_in_use_for_group_by=
00149 tbl->keys_in_use_for_order_by= tbl->getShare()->keys_in_use;
00150
00151
00152 if (index_hints)
00153 {
00154 key_map index_join[INDEX_HINT_FORCE + 1];
00155 key_map index_order[INDEX_HINT_FORCE + 1];
00156 key_map index_group[INDEX_HINT_FORCE + 1];
00157 bool have_empty_use_join= false, have_empty_use_order= false,
00158 have_empty_use_group= false;
00159 List_iterator <Index_hint> iter(index_hints->begin());
00160
00161
00162 for (int type= INDEX_HINT_IGNORE; type <= INDEX_HINT_FORCE; type++)
00163 {
00164 index_join[type].reset();
00165 index_order[type].reset();
00166 index_group[type].reset();
00167 }
00168
00169
00170 while (Index_hint* hint= iter++)
00171 {
00172
00173 if (hint->type == INDEX_HINT_USE && !hint->key_name)
00174 {
00175 if (hint->clause & INDEX_HINT_MASK_JOIN)
00176 {
00177 index_join[hint->type].reset();
00178 have_empty_use_join= true;
00179 }
00180 if (hint->clause & INDEX_HINT_MASK_ORDER)
00181 {
00182 index_order[hint->type].reset();
00183 have_empty_use_order= true;
00184 }
00185 if (hint->clause & INDEX_HINT_MASK_GROUP)
00186 {
00187 index_group[hint->type].reset();
00188 have_empty_use_group= true;
00189 }
00190 continue;
00191 }
00192
00193
00194
00195
00196
00197 uint32_t pos= tbl->getShare()->doesKeyNameExist(hint->key_name);
00198 if (pos == UINT32_MAX)
00199 {
00200 my_error(ER_KEY_DOES_NOT_EXITS, MYF(0), hint->key_name, alias);
00201 return 1;
00202 }
00203
00204 if (hint->clause & INDEX_HINT_MASK_JOIN)
00205 index_join[hint->type].set(pos);
00206 if (hint->clause & INDEX_HINT_MASK_ORDER)
00207 index_order[hint->type].set(pos);
00208 if (hint->clause & INDEX_HINT_MASK_GROUP)
00209 index_group[hint->type].set(pos);
00210 }
00211
00212
00213 if ((index_join[INDEX_HINT_FORCE].any() ||
00214 index_order[INDEX_HINT_FORCE].any() ||
00215 index_group[INDEX_HINT_FORCE].any()) &&
00216 (index_join[INDEX_HINT_USE].any() || have_empty_use_join ||
00217 index_order[INDEX_HINT_USE].any() || have_empty_use_order ||
00218 index_group[INDEX_HINT_USE].any() || have_empty_use_group))
00219 {
00220 my_error(ER_WRONG_USAGE, MYF(0), index_hint_type_name[INDEX_HINT_USE], index_hint_type_name[INDEX_HINT_FORCE]);
00221 return 1;
00222 }
00223
00224
00225 if (index_join[INDEX_HINT_FORCE].any() ||
00226 index_order[INDEX_HINT_FORCE].any() ||
00227 index_group[INDEX_HINT_FORCE].any())
00228 {
00229 tbl->force_index= true;
00230 index_join[INDEX_HINT_USE]|= index_join[INDEX_HINT_FORCE];
00231 index_order[INDEX_HINT_USE]|= index_order[INDEX_HINT_FORCE];
00232 index_group[INDEX_HINT_USE]|= index_group[INDEX_HINT_FORCE];
00233 }
00234
00235
00236 if (index_join[INDEX_HINT_USE].any() || have_empty_use_join)
00237 tbl->keys_in_use_for_query&= index_join[INDEX_HINT_USE];
00238 if (index_order[INDEX_HINT_USE].any() || have_empty_use_order)
00239 tbl->keys_in_use_for_order_by&= index_order[INDEX_HINT_USE];
00240 if (index_group[INDEX_HINT_USE].any() || have_empty_use_group)
00241 tbl->keys_in_use_for_group_by&= index_group[INDEX_HINT_USE];
00242
00243
00244 key_map_subtract(tbl->keys_in_use_for_query, index_join[INDEX_HINT_IGNORE]);
00245 key_map_subtract(tbl->keys_in_use_for_order_by, index_order[INDEX_HINT_IGNORE]);
00246 key_map_subtract(tbl->keys_in_use_for_group_by, index_group[INDEX_HINT_IGNORE]);
00247 }
00248
00249
00250 tbl->covering_keys&= tbl->keys_in_use_for_query;
00251 return 0;
00252 }
00253
00254 void TableList::print(Session *session, String *str)
00255 {
00256 if (nested_join)
00257 {
00258 str->append('(');
00259 print_join(session, str, &nested_join->join_list);
00260 str->append(')');
00261 }
00262 else
00263 {
00264 const char *cmp_name;
00265 if (derived)
00266 {
00267
00268 str->append('(');
00269 derived->print(str);
00270 str->append(')');
00271 cmp_name= "";
00272 }
00273 else
00274 {
00275
00276 str->append_identifier(str_ref(schema));
00277 str->append('.');
00278 str->append_identifier(str_ref(table_name));
00279 cmp_name= table_name;
00280 }
00281 if (table_alias_charset->strcasecmp(cmp_name, alias) && alias && alias[0])
00282 {
00283 str->append(' ');
00284 str->append_identifier(boost::to_lower_copy(string(alias)));
00285 }
00286
00287 if (index_hints)
00288 {
00289 List<Index_hint>::iterator it(index_hints->begin());
00290 while (Index_hint* hint= it++)
00291 {
00292 str->append(STRING_WITH_LEN(" "));
00293 hint->print(*str);
00294 }
00295 }
00296 }
00297 }
00298
00299 }