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 <boost/foreach.hpp>
00023 #include <boost/lexical_cast.hpp>
00024 #include <boost/exception/get_error_info.hpp>
00025 #include <string>
00026
00027 #include <drizzled/session.h>
00028 #include <drizzled/item/string.h>
00029 #include <drizzled/function/set_user_var.h>
00030 #include <drizzled/sql_lex.h>
00031 #include <drizzled/util/test.h>
00032
00033 using namespace std;
00034
00035 namespace drizzled
00036 {
00037
00058 int sql_set_variables(Session *session, const SetVarVector &var_list)
00059 {
00060 int error;
00061 BOOST_FOREACH(SetVarVector::const_reference it, var_list)
00062 {
00063 if ((error= it->check(session)))
00064 goto err;
00065 }
00066 if (!(error= test(session->is_error())))
00067 {
00068 BOOST_FOREACH(SetVarVector::const_reference it, var_list)
00069 {
00070 error|= it->update(session);
00071 }
00072 }
00073
00074 err:
00075 free_underlaid_joins(session, &session->lex().select_lex);
00076 return error;
00077 }
00078
00079
00080
00081
00082
00083 set_var::set_var(sql_var_t type_arg, sys_var *var_arg, str_ref base_name_arg, Item *value_arg) :
00084 uint64_t_value(0),
00085 var(var_arg),
00086 type(type_arg),
00087 base(base_name_arg)
00088 {
00089
00090
00091
00092
00093 if (value_arg && value_arg->type() == Item::FIELD_ITEM)
00094 {
00095 Item_field *item= (Item_field*) value_arg;
00096 value= new Item_string(str_ref(item->field_name), item->collation.collation);
00097 }
00098 else
00099 {
00100 value= value_arg;
00101 }
00102 }
00103
00104 int set_var::check(Session *session)
00105 {
00106 if (var->is_readonly())
00107 {
00108 my_error(ER_INCORRECT_GLOBAL_LOCAL_VAR, MYF(0), var->getName().c_str(), "read only");
00109 return -1;
00110 }
00111 if (var->check_type(type))
00112 {
00113 int err= type == OPT_GLOBAL ? ER_LOCAL_VARIABLE : ER_GLOBAL_VARIABLE;
00114 my_error(static_cast<drizzled::error_t>(err), MYF(0), var->getName().c_str());
00115 return -1;
00116 }
00117
00118 if (not value)
00119 {
00120 if (var->check_default(type))
00121 {
00122 my_error(ER_NO_DEFAULT, MYF(0), var->getName().c_str());
00123 return -1;
00124 }
00125 return 0;
00126 }
00127
00128 if ((!value->fixed &&
00129 value->fix_fields(session, &value)) || value->check_cols(1))
00130 return -1;
00131 if (var->check_update_type(value->result_type()))
00132 {
00133 my_error(ER_WRONG_TYPE_FOR_VAR, MYF(0), var->getName().c_str());
00134 return -1;
00135 }
00136 return var->check(session, this) ? -1 : 0;
00137 }
00138
00151 int set_var::update(Session *session)
00152 {
00153 try
00154 {
00155 if (not value)
00156 var->set_default(session, type);
00157 else if (var->update(session, this))
00158 return -1;
00159 if (var->getAfterUpdateTrigger())
00160 (*var->getAfterUpdateTrigger())(session, type);
00161 }
00162 catch (invalid_option_value &ex)
00163 {
00164
00165 string new_val= boost::lexical_cast<string>(uint64_t_value);
00166 if (boost::get_error_info<invalid_max_info>(ex) != NULL)
00167 {
00168 const uint64_t max_val= *(boost::get_error_info<invalid_max_info>(ex));
00169 string explanation("(> ");
00170 explanation.append(boost::lexical_cast<std::string>(max_val));
00171 explanation.push_back(')');
00172 push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
00173 ER_INVALID_OPTION_VALUE,
00174 ER(ER_INVALID_OPTION_VALUE),
00175 var->getName().c_str(),
00176 new_val.c_str(),
00177 explanation.c_str());
00178 }
00179 else if (boost::get_error_info<invalid_min_info>(ex) != NULL)
00180 {
00181 const int64_t min_val= *(boost::get_error_info<invalid_min_info>(ex));
00182 string explanation("(< ");
00183 explanation.append(boost::lexical_cast<std::string>(min_val));
00184 explanation.push_back(')');
00185 push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
00186 ER_INVALID_OPTION_VALUE,
00187 ER(ER_INVALID_OPTION_VALUE),
00188 var->getName().c_str(),
00189 new_val.c_str(),
00190 explanation.c_str());
00191 }
00192 else if (boost::get_error_info<invalid_value>(ex) != NULL)
00193 {
00194 const std::string str_val= *(boost::get_error_info<invalid_value>(ex));
00195 string explanation("(");
00196 explanation.append(str_val);
00197 explanation.push_back(')');
00198 push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
00199 ER_INVALID_OPTION_VALUE,
00200 ER(ER_INVALID_OPTION_VALUE),
00201 var->getName().c_str(),
00202 new_val.c_str(),
00203 explanation.c_str());
00204 }
00205 else
00206 {
00207 push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
00208 ER_INVALID_OPTION_VALUE,
00209 ER(ER_INVALID_OPTION_VALUE),
00210 var->getName().c_str(),
00211 new_val.c_str(),
00212 "");
00213 }
00214 }
00215 return 0;
00216 }
00217
00218
00219
00220
00221
00222 int set_var_user::check(Session *session)
00223 {
00224
00225
00226
00227
00228 return (user_var_item->fix_fields(session, (Item**) 0) ||
00229 user_var_item->check(0)) ? -1 : 0;
00230 }
00231
00232
00233 int set_var_user::update(Session *)
00234 {
00235 user_var_item->update();
00236 return 0;
00237 }
00238
00239 void set_var::setValue(const std::string &new_value)
00240 {
00241 str_value= new_value;
00242 }
00243
00244 void set_var::setValue(uint64_t new_value)
00245 {
00246 uint64_t_value= new_value;
00247 }
00248
00249 void set_var::updateValue()
00250 {
00251 if (var->show_type() != SHOW_CHAR)
00252 {
00253 uint64_t_value= value->val_int();
00254 }
00255 }
00256
00257
00258 }