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