00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <config.h>
00021
00022 #include <drizzled/session.h>
00023 #include <drizzled/error.h>
00024 #include <drizzled/show.h>
00025 #include <drizzled/item/ref.h>
00026 #include <drizzled/plugin/client.h>
00027 #include <drizzled/item/sum.h>
00028 #include <drizzled/item/subselect.h>
00029 #include <drizzled/sql_lex.h>
00030
00031 namespace drizzled {
00032
00033 Item_ref::Item_ref(Name_resolution_context *context_arg,
00034 Item **item, const char *table_name_arg,
00035 const char *field_name_arg,
00036 bool alias_name_used_arg)
00037 :Item_ident(context_arg, NULL, table_name_arg, field_name_arg),
00038 result_field(0), ref(item)
00039 {
00040 alias_name_used= alias_name_used_arg;
00041
00042
00043
00044 if (ref && *ref && (*ref)->fixed)
00045 set_properties();
00046 }
00047
00048
00113 bool Item_ref::fix_fields(Session *session, Item **reference)
00114 {
00115 enum_parsing_place place= NO_MATTER;
00116 assert(fixed == 0);
00117 Select_Lex *current_sel= session->lex().current_select;
00118
00119 if (!ref || ref == not_found_item)
00120 {
00121 if (!(ref= resolve_ref_in_select_and_group(session, this, context->select_lex)))
00122 return true;
00123
00124 if (ref == not_found_item)
00125 {
00126 Name_resolution_context *last_checked_context= context;
00127 Name_resolution_context *outer_context= context->outer_context;
00128 Field *from_field;
00129 ref= 0;
00130
00131 if (!outer_context)
00132 {
00133
00134 my_error(ER_BAD_FIELD_ERROR,MYF(0), full_name(), session->where());
00135 return true;
00136 }
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147 from_field= (Field*) not_found_field;
00148
00149 do
00150 {
00151 Select_Lex *select= outer_context->select_lex;
00152 Item_subselect *prev_subselect_item=
00153 last_checked_context->select_lex->master_unit()->item;
00154 last_checked_context= outer_context;
00155
00156
00157 if (outer_context->resolve_in_select_list)
00158 {
00159 if (!(ref= resolve_ref_in_select_and_group(session, this, select)))
00160 return true;
00161 if (ref != not_found_item)
00162 {
00163 assert(*ref && (*ref)->fixed);
00164 prev_subselect_item->used_tables_cache|= (*ref)->used_tables();
00165 prev_subselect_item->const_item_cache&= (*ref)->const_item();
00166 break;
00167 }
00168
00169
00170
00171
00172
00173 ref= 0;
00174 }
00175
00176 place= prev_subselect_item->parsing_place;
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189 if ((place != IN_HAVING ||
00190 (!select->with_sum_func &&
00191 select->group_list.elements == 0)))
00192 {
00193
00194
00195
00196
00197
00198 from_field= find_field_in_tables(session, this,
00199 outer_context->
00200 first_name_resolution_table,
00201 outer_context->
00202 last_name_resolution_table,
00203 reference,
00204 IGNORE_EXCEPT_NON_UNIQUE, true);
00205 if (! from_field)
00206 return true;
00207 if (from_field == view_ref_found)
00208 {
00209 Item::Type refer_type= (*reference)->type();
00210 prev_subselect_item->used_tables_cache|=
00211 (*reference)->used_tables();
00212 prev_subselect_item->const_item_cache&=
00213 (*reference)->const_item();
00214 assert((*reference)->type() == REF_ITEM);
00215 mark_as_dependent(session, last_checked_context->select_lex,
00216 context->select_lex, this,
00217 ((refer_type == REF_ITEM ||
00218 refer_type == FIELD_ITEM) ?
00219 (Item_ident*) (*reference) :
00220 0));
00221
00222
00223
00224
00225 return false;
00226 }
00227 if (from_field != not_found_field)
00228 {
00229 if (cached_table && cached_table->select_lex &&
00230 outer_context->select_lex &&
00231 cached_table->select_lex != outer_context->select_lex)
00232 {
00233
00234
00235
00236
00237
00238 do
00239 {
00240 outer_context= outer_context->outer_context;
00241 select= outer_context->select_lex;
00242 prev_subselect_item=
00243 last_checked_context->select_lex->master_unit()->item;
00244 last_checked_context= outer_context;
00245 } while (outer_context && outer_context->select_lex &&
00246 cached_table->select_lex != outer_context->select_lex);
00247 }
00248 prev_subselect_item->used_tables_cache|= from_field->getTable()->map;
00249 prev_subselect_item->const_item_cache= false;
00250 break;
00251 }
00252 }
00253 assert(from_field == not_found_field);
00254
00255
00256 prev_subselect_item->used_tables_cache|= OUTER_REF_TABLE_BIT;
00257 prev_subselect_item->const_item_cache= false;
00258
00259 outer_context= outer_context->outer_context;
00260 } while (outer_context);
00261
00262 assert(from_field != 0 && from_field != view_ref_found);
00263 if (from_field != not_found_field)
00264 {
00265 Item_field* fld;
00266 fld= new Item_field(from_field);
00267 *reference= fld;
00268 mark_as_dependent(session, last_checked_context->select_lex,
00269 session->lex().current_select, this, fld);
00270
00271
00272
00273
00274
00275 if (session->lex().in_sum_func &&
00276 session->lex().in_sum_func->nest_level >=
00277 last_checked_context->select_lex->nest_level)
00278 set_if_bigger(session->lex().in_sum_func->max_arg_level,
00279 last_checked_context->select_lex->nest_level);
00280 return false;
00281 }
00282 if (ref == 0)
00283 {
00284
00285 my_error(ER_BAD_FIELD_ERROR, MYF(0), full_name(), session->where());
00286 return true;
00287 }
00288
00289 assert(*ref && (*ref)->fixed);
00290 mark_as_dependent(session, last_checked_context->select_lex,
00291 context->select_lex, this, this);
00292
00293
00294
00295
00296
00297 if (session->lex().in_sum_func &&
00298 session->lex().in_sum_func->nest_level >=
00299 last_checked_context->select_lex->nest_level)
00300 set_if_bigger(session->lex().in_sum_func->max_arg_level,
00301 last_checked_context->select_lex->nest_level);
00302 }
00303 }
00304
00305 assert(*ref);
00306
00307
00308
00309
00310
00311
00312 if (!((*ref)->type() == REF_ITEM &&
00313 ((Item_ref *)(*ref))->ref_type() == OUTER_REF) &&
00314 (((*ref)->with_sum_func && name &&
00315 !(current_sel->linkage != GLOBAL_OPTIONS_TYPE &&
00316 current_sel->having_fix_field)) ||
00317 !(*ref)->fixed))
00318 {
00319 my_error(ER_ILLEGAL_REFERENCE, MYF(0), name, ((*ref)->with_sum_func ? "reference to group function" : "forward reference in item list"));
00320 return true;
00321 }
00322
00323 set_properties();
00324
00325 if ((*ref)->check_cols(1))
00326 return true;
00327 return false;
00328 }
00329
00330
00331 void Item_ref::set_properties()
00332 {
00333 max_length= (*ref)->max_length;
00334 maybe_null= (*ref)->maybe_null;
00335 decimals= (*ref)->decimals;
00336 collation.set((*ref)->collation);
00337
00338
00339
00340
00341 with_sum_func= (*ref)->with_sum_func;
00342 unsigned_flag= (*ref)->unsigned_flag;
00343 fixed= 1;
00344 if (alias_name_used)
00345 return;
00346 if ((*ref)->type() == FIELD_ITEM)
00347 alias_name_used= ((Item_ident *) (*ref))->alias_name_used;
00348 else
00349 alias_name_used= true;
00350 }
00351
00352
00353 void Item_ref::cleanup()
00354 {
00355 Item_ident::cleanup();
00356 result_field= 0;
00357 return;
00358 }
00359
00360
00361 void Item_ref::print(String *str)
00362 {
00363 if (ref)
00364 {
00365 if ((*ref)->type() != Item::CACHE_ITEM &&
00366 !table_name && name && alias_name_used)
00367 {
00368 str->append_identifier(str_ref(name));
00369 }
00370 else
00371 (*ref)->print(str);
00372 }
00373 else
00374 Item_ident::print(str);
00375 }
00376
00377
00378 void Item_ref::send(plugin::Client *client, String *tmp)
00379 {
00380 if (result_field)
00381 {
00382 client->store(result_field);
00383 return;
00384 }
00385 return (*ref)->send(client, tmp);
00386 }
00387
00388
00389 double Item_ref::val_result()
00390 {
00391 if (result_field)
00392 {
00393 if ((null_value= result_field->is_null()))
00394 return 0.0;
00395 return result_field->val_real();
00396 }
00397 return val_real();
00398 }
00399
00400
00401 int64_t Item_ref::val_int_result()
00402 {
00403 if (result_field)
00404 {
00405 if ((null_value= result_field->is_null()))
00406 return 0;
00407 return result_field->val_int();
00408 }
00409 return val_int();
00410 }
00411
00412
00413 String *Item_ref::str_result(String* str)
00414 {
00415 if (result_field)
00416 {
00417 if ((null_value= result_field->is_null()))
00418 return 0;
00419 str->set_charset(str_value.charset());
00420 return result_field->val_str(str, &str_value);
00421 }
00422 return val_str(str);
00423 }
00424
00425
00426 type::Decimal *Item_ref::val_decimal_result(type::Decimal *decimal_value)
00427 {
00428 if (result_field)
00429 {
00430 if ((null_value= result_field->is_null()))
00431 return 0;
00432 return result_field->val_decimal(decimal_value);
00433 }
00434 return val_decimal(decimal_value);
00435 }
00436
00437
00438 bool Item_ref::val_bool_result()
00439 {
00440 if (result_field)
00441 {
00442 if ((null_value= result_field->is_null()))
00443 return 0;
00444 switch (result_field->result_type()) {
00445 case INT_RESULT:
00446 return result_field->val_int() != 0;
00447
00448 case DECIMAL_RESULT:
00449 {
00450 type::Decimal decimal_value;
00451 type::Decimal *val= result_field->val_decimal(&decimal_value);
00452 if (val)
00453 return not val->isZero();
00454 return 0;
00455 }
00456
00457 case REAL_RESULT:
00458 case STRING_RESULT:
00459 return result_field->val_real() != 0.0;
00460
00461 case ROW_RESULT:
00462 assert(0);
00463 }
00464 }
00465
00466 return val_bool();
00467 }
00468
00469
00470 double Item_ref::val_real()
00471 {
00472 assert(fixed);
00473 double tmp=(*ref)->val_result();
00474 null_value=(*ref)->null_value;
00475 return tmp;
00476 }
00477
00478
00479 int64_t Item_ref::val_int()
00480 {
00481 assert(fixed);
00482 int64_t tmp=(*ref)->val_int_result();
00483 null_value=(*ref)->null_value;
00484 return tmp;
00485 }
00486
00487
00488 bool Item_ref::val_bool()
00489 {
00490 assert(fixed);
00491 bool tmp= (*ref)->val_bool_result();
00492 null_value= (*ref)->null_value;
00493 return tmp;
00494 }
00495
00496
00497 String *Item_ref::val_str(String* tmp)
00498 {
00499 assert(fixed);
00500 tmp=(*ref)->str_result(tmp);
00501 null_value=(*ref)->null_value;
00502 return tmp;
00503 }
00504
00505
00506 bool Item_ref::is_null()
00507 {
00508 assert(fixed);
00509 return (*ref)->is_null();
00510 }
00511
00512
00513 bool Item_ref::get_date(type::Time <ime,uint32_t fuzzydate)
00514 {
00515 return (null_value=(*ref)->get_date_result(ltime,fuzzydate));
00516 }
00517
00518
00519 type::Decimal *Item_ref::val_decimal(type::Decimal *decimal_value)
00520 {
00521 type::Decimal *val= (*ref)->val_decimal_result(decimal_value);
00522 null_value= (*ref)->null_value;
00523 return val;
00524 }
00525
00526 int Item_ref::save_in_field(Field *to, bool no_conversions)
00527 {
00528 int res;
00529 assert(!result_field);
00530 res= (*ref)->save_in_field(to, no_conversions);
00531 null_value= (*ref)->null_value;
00532 return res;
00533 }
00534
00535
00536 void Item_ref::save_org_in_field(Field *field)
00537 {
00538 (*ref)->save_org_in_field(field);
00539 }
00540
00541
00542 void Item_ref::make_field(SendField *field)
00543 {
00544 (*ref)->make_field(field);
00545
00546 if (name)
00547 field->col_name= name;
00548 if (table_name)
00549 field->table_name= table_name;
00550 if (db_name)
00551 field->db_name= db_name;
00552 }
00553
00554
00555 Item *Item_ref::get_tmp_table_item(Session *session)
00556 {
00557 if (!result_field)
00558 return (*ref)->get_tmp_table_item(session);
00559
00560 Item_field *item= new Item_field(result_field);
00561 if (item)
00562 {
00563 item->table_name= table_name;
00564 item->db_name= db_name;
00565 }
00566 return item;
00567 }
00568
00569 void Item_ref::fix_after_pullout(Select_Lex *new_parent, Item **)
00570 {
00571 if (depended_from == new_parent)
00572 {
00573 (*ref)->fix_after_pullout(new_parent, ref);
00574 depended_from= NULL;
00575 }
00576 }
00577
00578 }