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