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 void
00102 Item_func_set_user_var::update_hash(data_ref data,
00103 Item_result res_type,
00104 const charset_info_st * 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 entry->update_hash((null_value= args[0]->null_value), data, res_type, cs, dv, unsigned_arg);
00114 }
00115
00130 bool
00131 Item_func_set_user_var::check(bool use_result_field)
00132 {
00133 if (use_result_field && !result_field)
00134 use_result_field= false;
00135
00136 switch (cached_result_type) {
00137 case REAL_RESULT:
00138 {
00139 save_result.vreal= use_result_field ? result_field->val_real() :
00140 args[0]->val_real();
00141 break;
00142 }
00143 case INT_RESULT:
00144 {
00145 save_result.vint= use_result_field ? result_field->val_int() :
00146 args[0]->val_int();
00147
00148 unsigned_flag= use_result_field ? ((Field_num*)result_field)->unsigned_flag:
00149 args[0]->unsigned_flag;
00150
00151 break;
00152 }
00153 case STRING_RESULT:
00154 {
00155 save_result.vstr= use_result_field ? result_field->val_str_internal(&value) :
00156 args[0]->val_str(&value);
00157 break;
00158 }
00159 case DECIMAL_RESULT:
00160 {
00161 save_result.vdec= use_result_field ?
00162 result_field->val_decimal(&decimal_buff) :
00163 args[0]->val_decimal(&decimal_buff);
00164 break;
00165 }
00166 case ROW_RESULT:
00167
00168 assert(0);
00169 break;
00170 }
00171
00172 return false;
00173 }
00174
00190 void
00191 Item_func_set_user_var::update()
00192 {
00193 switch (cached_result_type) {
00194 case REAL_RESULT:
00195 {
00196 update_hash(data_ref(&save_result.vreal, sizeof(save_result.vreal)), REAL_RESULT, &my_charset_bin, DERIVATION_IMPLICIT, 0);
00197 break;
00198 }
00199
00200 case INT_RESULT:
00201 {
00202 update_hash(data_ref(&save_result.vint, sizeof(save_result.vint)), INT_RESULT, &my_charset_bin, DERIVATION_IMPLICIT, unsigned_flag);
00203 break;
00204 }
00205
00206 case STRING_RESULT:
00207 {
00208 if (!save_result.vstr)
00209 update_hash(data_ref(), STRING_RESULT, &my_charset_bin, DERIVATION_IMPLICIT, 0);
00210 else
00211 update_hash(*save_result.vstr, STRING_RESULT, save_result.vstr->charset(), DERIVATION_IMPLICIT, 0);
00212 break;
00213 }
00214
00215 case DECIMAL_RESULT:
00216 {
00217 if (!save_result.vdec)
00218 update_hash(data_ref(), DECIMAL_RESULT, &my_charset_bin, DERIVATION_IMPLICIT, 0);
00219 else
00220 update_hash(data_ref(save_result.vdec, sizeof(type::Decimal)), DECIMAL_RESULT, &my_charset_bin, DERIVATION_IMPLICIT, 0);
00221 break;
00222 }
00223
00224 case ROW_RESULT:
00225
00226 assert(false);
00227 break;
00228 }
00229 }
00230
00231 double Item_func_set_user_var::val_real()
00232 {
00233 assert(fixed == 1);
00234 check(0);
00235 update();
00236 return entry->val_real(&null_value);
00237 }
00238
00239 int64_t Item_func_set_user_var::val_int()
00240 {
00241 assert(fixed == 1);
00242 check(0);
00243 update();
00244 return entry->val_int(&null_value);
00245 }
00246
00247 String *Item_func_set_user_var::val_str(String *str)
00248 {
00249 assert(fixed == 1);
00250 check(0);
00251 update();
00252 return entry->val_str(&null_value, str, decimals);
00253 }
00254
00255
00256 type::Decimal *Item_func_set_user_var::val_decimal(type::Decimal *val)
00257 {
00258 assert(fixed == 1);
00259 check(0);
00260 update();
00261 return entry->val_decimal(&null_value, val);
00262 }
00263
00264 double Item_func_set_user_var::val_result()
00265 {
00266 assert(fixed == 1);
00267 check(true);
00268 update();
00269 return entry->val_real(&null_value);
00270 }
00271
00272 int64_t Item_func_set_user_var::val_int_result()
00273 {
00274 assert(fixed == 1);
00275 check(true);
00276 update();
00277 return entry->val_int(&null_value);
00278 }
00279
00280 String *Item_func_set_user_var::str_result(String *str)
00281 {
00282 assert(fixed == 1);
00283 check(true);
00284 update();
00285 return entry->val_str(&null_value, str, decimals);
00286 }
00287
00288
00289 type::Decimal *Item_func_set_user_var::val_decimal_result(type::Decimal *val)
00290 {
00291 assert(fixed == 1);
00292 check(true);
00293 update();
00294 return entry->val_decimal(&null_value, val);
00295 }
00296
00297 void Item_func_set_user_var::print(String *str)
00298 {
00299 str->append(STRING_WITH_LEN("(@"));
00300 str->append(name);
00301 str->append(STRING_WITH_LEN(":="));
00302 args[0]->print(str);
00303 str->append(')');
00304 }
00305
00306 void Item_func_set_user_var::send(plugin::Client *client, String *str_arg)
00307 {
00308 if (result_field)
00309 {
00310 check(1);
00311 update();
00312 client->store(result_field);
00313 return;
00314 }
00315 Item::send(client, str_arg);
00316 }
00317
00318 void Item_func_set_user_var::make_field(SendField *tmp_field)
00319 {
00320 if (result_field)
00321 {
00322 result_field->make_field(tmp_field);
00323 assert(tmp_field->table_name != 0);
00324 if (Item::name)
00325 tmp_field->col_name=Item::name;
00326 }
00327 else
00328 {
00329 Item::make_field(tmp_field);
00330 }
00331 }
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
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 int Item_func_set_user_var::save_in_field(Field *field, bool no_conversions,
00372 bool can_use_result_field)
00373 {
00374 bool use_result_field= (!can_use_result_field ? 0 :
00375 (result_field && result_field != field));
00376 int error;
00377
00378
00379 check(use_result_field);
00380 update();
00381
00382 if (result_type() == STRING_RESULT ||
00383 (result_type() == REAL_RESULT && field->result_type() == STRING_RESULT))
00384 {
00385 String *result;
00386 const charset_info_st * const cs= collation.collation;
00387 char buff[MAX_FIELD_WIDTH];
00388 str_value.set_quick(buff, sizeof(buff), cs);
00389 result= entry->val_str(&null_value, &str_value, decimals);
00390
00391 if (null_value)
00392 {
00393 str_value.set_quick(0, 0, cs);
00394 return set_field_to_null_with_conversions(field, no_conversions);
00395 }
00396
00397
00398
00399 field->set_notnull();
00400 error=field->store(result->ptr(),result->length(),cs);
00401 str_value.set_quick(0, 0, cs);
00402 }
00403 else if (result_type() == REAL_RESULT)
00404 {
00405 double nr= entry->val_real(&null_value);
00406 if (null_value)
00407 return set_field_to_null(field);
00408 field->set_notnull();
00409 error=field->store(nr);
00410 }
00411 else if (result_type() == DECIMAL_RESULT)
00412 {
00413 type::Decimal decimal_value;
00414 type::Decimal *val= entry->val_decimal(&null_value, &decimal_value);
00415 if (null_value)
00416 return set_field_to_null(field);
00417 field->set_notnull();
00418 error=field->store_decimal(val);
00419 }
00420 else
00421 {
00422 int64_t nr= entry->val_int(&null_value);
00423 if (null_value)
00424 return set_field_to_null_with_conversions(field, no_conversions);
00425 field->set_notnull();
00426 error=field->store(nr, unsigned_flag);
00427 }
00428 return error;
00429 }
00430
00431
00432 }