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/function/set_user_var.h>
00023 #include <drizzled/field/num.h>
00024 #include <drizzled/session.h>
00025 #include <drizzled/plugin/client.h>
00026 #include <drizzled/user_var_entry.h>
00027 #include <drizzled/table.h>
00028
00029 namespace drizzled {
00030
00031
00032
00033
00034
00035
00036 bool Item_func_set_user_var::fix_fields(Session *session, Item **ref)
00037 {
00038 assert(fixed == 0);
00039
00040 if (Item_func::fix_fields(session, ref) ||
00041 !(entry= session->getVariable(name, true)))
00042 return true;
00043
00044
00045
00046
00047
00048 entry->update_query_id= session->getQueryId();
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064 null_item= (args[0]->type() == NULL_ITEM);
00065 if (!entry->collation.collation || !null_item)
00066 entry->collation.set(args[0]->collation.collation, DERIVATION_IMPLICIT);
00067 collation.set(entry->collation.collation, DERIVATION_IMPLICIT);
00068 cached_result_type= args[0]->result_type();
00069 return false;
00070 }
00071
00072 void
00073 Item_func_set_user_var::fix_length_and_dec()
00074 {
00075 maybe_null=args[0]->maybe_null;
00076 max_length=args[0]->max_length;
00077 decimals=args[0]->decimals;
00078 collation.set(args[0]->collation.collation, DERIVATION_IMPLICIT);
00079 }
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089 bool Item_func_set_user_var::register_field_in_read_map(unsigned char *arg)
00090 {
00091 if (result_field)
00092 {
00093 Table *table= (Table *) arg;
00094 if (result_field->getTable() == table || !table)
00095 result_field->getTable()->setReadSet(result_field->position());
00096 }
00097 return 0;
00098 }
00099
00100
00101 bool
00102 Item_func_set_user_var::update_hash(void *ptr, uint32_t length,
00103 Item_result res_type,
00104 const CHARSET_INFO * const cs, Derivation dv,
00105 bool unsigned_arg)
00106 {
00107
00108
00109
00110
00111 if ((null_value= args[0]->null_value) && null_item)
00112 res_type= entry->type;
00113 if (entry->update_hash((null_value= args[0]->null_value),
00114 ptr, length, res_type, cs, dv, unsigned_arg))
00115 {
00116 null_value= 1;
00117 return 1;
00118 }
00119 return 0;
00120 }
00121
00136 bool
00137 Item_func_set_user_var::check(bool use_result_field)
00138 {
00139 if (use_result_field && !result_field)
00140 use_result_field= false;
00141
00142 switch (cached_result_type) {
00143 case REAL_RESULT:
00144 {
00145 save_result.vreal= use_result_field ? result_field->val_real() :
00146 args[0]->val_real();
00147 break;
00148 }
00149 case INT_RESULT:
00150 {
00151 save_result.vint= use_result_field ? result_field->val_int() :
00152 args[0]->val_int();
00153 unsigned_flag= use_result_field ? ((Field_num*)result_field)->unsigned_flag:
00154 args[0]->unsigned_flag;
00155 break;
00156 }
00157 case STRING_RESULT:
00158 {
00159 save_result.vstr= use_result_field ? result_field->val_str_internal(&value) :
00160 args[0]->val_str(&value);
00161 break;
00162 }
00163 case DECIMAL_RESULT:
00164 {
00165 save_result.vdec= use_result_field ?
00166 result_field->val_decimal(&decimal_buff) :
00167 args[0]->val_decimal(&decimal_buff);
00168 break;
00169 }
00170 case ROW_RESULT:
00171
00172 assert(0);
00173 break;
00174 }
00175
00176 return false;
00177 }
00178
00194 bool
00195 Item_func_set_user_var::update()
00196 {
00197 bool res= false;
00198
00199 switch (cached_result_type) {
00200 case REAL_RESULT:
00201 {
00202 res= update_hash((void*) &save_result.vreal,sizeof(save_result.vreal),
00203 REAL_RESULT, &my_charset_bin, DERIVATION_IMPLICIT, 0);
00204 break;
00205 }
00206
00207 case INT_RESULT:
00208 {
00209 res= update_hash((void*) &save_result.vint, sizeof(save_result.vint),
00210 INT_RESULT, &my_charset_bin, DERIVATION_IMPLICIT,
00211 unsigned_flag);
00212 break;
00213 }
00214
00215 case STRING_RESULT:
00216 {
00217 if (!save_result.vstr)
00218 res= update_hash((void*) 0, 0, STRING_RESULT, &my_charset_bin,
00219 DERIVATION_IMPLICIT, 0);
00220 else
00221 res= update_hash((void*) save_result.vstr->ptr(),
00222 save_result.vstr->length(), STRING_RESULT,
00223 save_result.vstr->charset(),
00224 DERIVATION_IMPLICIT, 0);
00225 break;
00226 }
00227
00228 case DECIMAL_RESULT:
00229 {
00230 if (!save_result.vdec)
00231 res= update_hash((void*) 0, 0, DECIMAL_RESULT, &my_charset_bin,
00232 DERIVATION_IMPLICIT, 0);
00233 else
00234 res= update_hash((void*) save_result.vdec,
00235 sizeof(type::Decimal), DECIMAL_RESULT,
00236 &my_charset_bin, DERIVATION_IMPLICIT, 0);
00237 break;
00238 }
00239
00240 case ROW_RESULT:
00241
00242 assert(0);
00243 break;
00244 }
00245
00246 return(res);
00247 }
00248
00249 double Item_func_set_user_var::val_real()
00250 {
00251 assert(fixed == 1);
00252 check(0);
00253 update();
00254 return entry->val_real(&null_value);
00255 }
00256
00257 int64_t Item_func_set_user_var::val_int()
00258 {
00259 assert(fixed == 1);
00260 check(0);
00261 update();
00262 return entry->val_int(&null_value);
00263 }
00264
00265 String *Item_func_set_user_var::val_str(String *str)
00266 {
00267 assert(fixed == 1);
00268 check(0);
00269 update();
00270 return entry->val_str(&null_value, str, decimals);
00271 }
00272
00273
00274 type::Decimal *Item_func_set_user_var::val_decimal(type::Decimal *val)
00275 {
00276 assert(fixed == 1);
00277 check(0);
00278 update();
00279 return entry->val_decimal(&null_value, val);
00280 }
00281
00282 double Item_func_set_user_var::val_result()
00283 {
00284 assert(fixed == 1);
00285 check(true);
00286 update();
00287 return entry->val_real(&null_value);
00288 }
00289
00290 int64_t Item_func_set_user_var::val_int_result()
00291 {
00292 assert(fixed == 1);
00293 check(true);
00294 update();
00295 return entry->val_int(&null_value);
00296 }
00297
00298 String *Item_func_set_user_var::str_result(String *str)
00299 {
00300 assert(fixed == 1);
00301 check(true);
00302 update();
00303 return entry->val_str(&null_value, str, decimals);
00304 }
00305
00306
00307 type::Decimal *Item_func_set_user_var::val_decimal_result(type::Decimal *val)
00308 {
00309 assert(fixed == 1);
00310 check(true);
00311 update();
00312 return entry->val_decimal(&null_value, val);
00313 }
00314
00315 void Item_func_set_user_var::print(String *str)
00316 {
00317 str->append(STRING_WITH_LEN("(@"));
00318 str->append(name.str, name.length);
00319 str->append(STRING_WITH_LEN(":="));
00320 args[0]->print(str);
00321 str->append(')');
00322 }
00323
00324 bool Item_func_set_user_var::send(plugin::Client *client, String *str_arg)
00325 {
00326 if (result_field)
00327 {
00328 check(1);
00329 update();
00330 return client->store(result_field);
00331 }
00332 return Item::send(client, str_arg);
00333 }
00334
00335 void Item_func_set_user_var::make_field(SendField *tmp_field)
00336 {
00337 if (result_field)
00338 {
00339 result_field->make_field(tmp_field);
00340 assert(tmp_field->table_name != 0);
00341 if (Item::name)
00342 tmp_field->col_name=Item::name;
00343 }
00344 else
00345 {
00346 Item::make_field(tmp_field);
00347 }
00348 }
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388 int Item_func_set_user_var::save_in_field(Field *field, bool no_conversions,
00389 bool can_use_result_field)
00390 {
00391 bool use_result_field= (!can_use_result_field ? 0 :
00392 (result_field && result_field != field));
00393 int error;
00394
00395
00396 check(use_result_field);
00397 update();
00398
00399 if (result_type() == STRING_RESULT ||
00400 (result_type() == REAL_RESULT && field->result_type() == STRING_RESULT))
00401 {
00402 String *result;
00403 const CHARSET_INFO * const cs= collation.collation;
00404 char buff[MAX_FIELD_WIDTH];
00405 str_value.set_quick(buff, sizeof(buff), cs);
00406 result= entry->val_str(&null_value, &str_value, decimals);
00407
00408 if (null_value)
00409 {
00410 str_value.set_quick(0, 0, cs);
00411 return set_field_to_null_with_conversions(field, no_conversions);
00412 }
00413
00414
00415
00416 field->set_notnull();
00417 error=field->store(result->ptr(),result->length(),cs);
00418 str_value.set_quick(0, 0, cs);
00419 }
00420 else if (result_type() == REAL_RESULT)
00421 {
00422 double nr= entry->val_real(&null_value);
00423 if (null_value)
00424 return set_field_to_null(field);
00425 field->set_notnull();
00426 error=field->store(nr);
00427 }
00428 else if (result_type() == DECIMAL_RESULT)
00429 {
00430 type::Decimal decimal_value;
00431 type::Decimal *val= entry->val_decimal(&null_value, &decimal_value);
00432 if (null_value)
00433 return set_field_to_null(field);
00434 field->set_notnull();
00435 error=field->store_decimal(val);
00436 }
00437 else
00438 {
00439 int64_t nr= entry->val_int(&null_value);
00440 if (null_value)
00441 return set_field_to_null_with_conversions(field, no_conversions);
00442 field->set_notnull();
00443 error=field->store(nr, unsigned_flag);
00444 }
00445 return error;
00446 }
00447
00448
00449 }