Drizzled Public API Documentation

set_var.cc
1 /* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3  *
4  * Copyright (C) 2008 Sun Microsystems, Inc.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; version 2 of the License.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18  */
19 
20 #include <config.h>
21 
22 #include <boost/foreach.hpp>
23 #include <boost/lexical_cast.hpp>
24 #include <boost/exception/get_error_info.hpp>
25 #include <string>
26 
27 #include <drizzled/session.h>
28 #include <drizzled/item/string.h>
29 #include <drizzled/function/set_user_var.h>
30 #include <drizzled/sql_lex.h>
31 #include <drizzled/util/test.h>
32 
33 using namespace std;
34 
35 namespace drizzled
36 {
37 
58 int sql_set_variables(Session *session, const SetVarVector &var_list)
59 {
60  int error;
61  BOOST_FOREACH(SetVarVector::const_reference it, var_list)
62  {
63  if ((error= it->check(session)))
64  goto err;
65  }
66  if (!(error= test(session->is_error())))
67  {
68  BOOST_FOREACH(SetVarVector::const_reference it, var_list)
69  {
70  error|= it->update(session); // Returns 0, -1 or 1
71  }
72  }
73 
74 err:
75  free_underlaid_joins(session, &session->lex().select_lex);
76  return error;
77 }
78 
79 
80 /*****************************************************************************
81  Functions to handle SET mysql_internal_variable=const_expr
82 *****************************************************************************/
83 set_var::set_var(sql_var_t type_arg, sys_var *var_arg, str_ref base_name_arg, Item *value_arg) :
84  uint64_t_value(0),
85  var(var_arg),
86  type(type_arg),
87  base(base_name_arg)
88 {
89  /*
90  If the set value is a field, change it to a string to allow things like
91  SET table_type=MYISAM;
92  */
93  if (value_arg && value_arg->type() == Item::FIELD_ITEM)
94  {
95  Item_field *item= (Item_field*) value_arg;
96  value= new Item_string(str_ref(item->field_name), item->collation.collation);
97  }
98  else
99  {
100  value= value_arg;
101  }
102 }
103 
104 int set_var::check(Session *session)
105 {
106  if (var->is_readonly())
107  {
108  my_error(ER_INCORRECT_GLOBAL_LOCAL_VAR, MYF(0), var->getName().c_str(), "read only");
109  return -1;
110  }
111  if (var->check_type(type))
112  {
113  int err= type == OPT_GLOBAL ? ER_LOCAL_VARIABLE : ER_GLOBAL_VARIABLE;
114  my_error(static_cast<drizzled::error_t>(err), MYF(0), var->getName().c_str());
115  return -1;
116  }
117  /* value is a NULL pointer if we are using SET ... = DEFAULT */
118  if (not value)
119  {
120  if (var->check_default(type))
121  {
122  my_error(ER_NO_DEFAULT, MYF(0), var->getName().c_str());
123  return -1;
124  }
125  return 0;
126  }
127 
128  if ((!value->fixed &&
129  value->fix_fields(session, &value)) || value->check_cols(1))
130  return -1;
131  if (var->check_update_type(value->result_type()))
132  {
133  my_error(ER_WRONG_TYPE_FOR_VAR, MYF(0), var->getName().c_str());
134  return -1;
135  }
136  return var->check(session, this) ? -1 : 0;
137 }
138 
151 int set_var::update(Session *session)
152 {
153  try
154  {
155  if (not value)
156  var->set_default(session, type);
157  else if (var->update(session, this))
158  return -1; // should never happen
159  if (var->getAfterUpdateTrigger())
160  (*var->getAfterUpdateTrigger())(session, type);
161  }
162  catch (invalid_option_value &ex)
163  {
164  /* TODO: Fix this to be typesafe once we have properly typed set_var */
165  string new_val= boost::lexical_cast<string>(uint64_t_value);
166  if (boost::get_error_info<invalid_max_info>(ex) != NULL)
167  {
168  const uint64_t max_val= *(boost::get_error_info<invalid_max_info>(ex));
169  string explanation("(> ");
170  explanation.append(boost::lexical_cast<std::string>(max_val));
171  explanation.push_back(')');
172  push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
173  ER_INVALID_OPTION_VALUE,
174  ER(ER_INVALID_OPTION_VALUE),
175  var->getName().c_str(),
176  new_val.c_str(),
177  explanation.c_str());
178  }
179  else if (boost::get_error_info<invalid_min_info>(ex) != NULL)
180  {
181  const int64_t min_val= *(boost::get_error_info<invalid_min_info>(ex));
182  string explanation("(< ");
183  explanation.append(boost::lexical_cast<std::string>(min_val));
184  explanation.push_back(')');
185  push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
186  ER_INVALID_OPTION_VALUE,
187  ER(ER_INVALID_OPTION_VALUE),
188  var->getName().c_str(),
189  new_val.c_str(),
190  explanation.c_str());
191  }
192  else if (boost::get_error_info<invalid_value>(ex) != NULL)
193  {
194  const std::string str_val= *(boost::get_error_info<invalid_value>(ex));
195  string explanation("(");
196  explanation.append(str_val);
197  explanation.push_back(')');
198  push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
199  ER_INVALID_OPTION_VALUE,
200  ER(ER_INVALID_OPTION_VALUE),
201  var->getName().c_str(),
202  new_val.c_str(),
203  explanation.c_str());
204  }
205  else
206  {
207  push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
208  ER_INVALID_OPTION_VALUE,
209  ER(ER_INVALID_OPTION_VALUE),
210  var->getName().c_str(),
211  new_val.c_str(),
212  "");
213  }
214  }
215  return 0;
216 }
217 
218 /*****************************************************************************
219  Functions to handle SET @user_variable=const_expr
220 *****************************************************************************/
221 
222 int set_var_user::check(Session *session)
223 {
224  /*
225  Item_func_set_user_var can't substitute something else on its place =>
226  0 can be passed as last argument (reference on item)
227  */
228  return (user_var_item->fix_fields(session, (Item**) 0) ||
229  user_var_item->check(0)) ? -1 : 0;
230 }
231 
232 
233 int set_var_user::update(Session *)
234 {
235  user_var_item->update();
236  return 0;
237 }
238 
239 void set_var::setValue(const std::string &new_value)
240 {
241  str_value= new_value;
242 }
243 
244 void set_var::setValue(uint64_t new_value)
245 {
246  uint64_t_value= new_value;
247 }
248 
249 void set_var::updateValue()
250 {
251  if (var->show_type() != SHOW_CHAR)
252  {
253  uint64_t_value= value->val_int();
254  }
255 }
256 
257 
258 } /* namespace drizzled */
int sql_set_variables(Session *session, const SetVarVector &var_list)
Definition: set_var.cc:58
TODO: Rename this file - func.h is stupid.
void free_underlaid_joins(Session *session, Select_Lex *select)
Definition: sql_select.cc:6655
bool is_error() const
Definition: session.cc:1871