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