~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/set_var.cc

  • Committer: Monty Taylor
  • Date: 2010-10-21 23:10:12 UTC
  • mto: (1879.1.2 build)
  • mto: This revision was merged to the branch mainline in revision 1880.
  • Revision ID: mordred@inaugust.com-20101021231012-uhsebiqo23xi0ygy
Updated AUTHORS list with everyone from bzr logs.

Show diffs side-by-side

added added

removed removed

Lines of Context:
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/lexical_cast.hpp>
23
 
#include <boost/exception/get_error_info.hpp>
24
 
#include <string>
25
 
 
26
 
#include <drizzled/session.h>
27
 
#include <drizzled/item/string.h>
28
 
#include <drizzled/sql_list.h>
29
 
#include <drizzled/function/set_user_var.h>
30
 
 
31
 
using namespace std;
32
 
 
33
 
namespace drizzled
34
 
{
35
 
 
36
 
/**
37
 
  Execute update of all variables.
38
 
 
39
 
  First run a check of all variables that all updates will go ok.
40
 
  If yes, then execute all updates, returning an error if any one failed.
41
 
 
42
 
  This should ensure that in all normal cases none all or variables are
43
 
  updated.
44
 
 
45
 
  @param Session                Thread id
46
 
  @param var_list       List of variables to update
47
 
 
48
 
  @retval
49
 
    0   ok
50
 
  @retval
51
 
    1   ERROR, message sent (normally no variables was updated)
52
 
  @retval
53
 
    -1  ERROR, message not sent
54
 
*/
55
 
 
56
 
int sql_set_variables(Session *session, const SetVarVector &var_list)
57
 
{
58
 
  int error;
59
 
 
60
 
  SetVarVector::const_iterator it(var_list.begin());
61
 
 
62
 
  while (it != var_list.end())
63
 
  {
64
 
    if ((error= (*it)->check(session)))
65
 
      goto err;
66
 
    ++it;
67
 
  }
68
 
  if (!(error= test(session->is_error())))
69
 
  {
70
 
    it= var_list.begin();
71
 
    while (it != var_list.end())
72
 
    {
73
 
      error|= (*it)->update(session);         // Returns 0, -1 or 1
74
 
      ++it;
75
 
    }
76
 
  }
77
 
 
78
 
err:
79
 
  free_underlaid_joins(session, &session->getLex()->select_lex);
80
 
  return(error);
81
 
}
82
 
 
83
 
 
84
 
/*****************************************************************************
85
 
  Functions to handle SET mysql_internal_variable=const_expr
86
 
*****************************************************************************/
87
 
set_var::set_var(sql_var_t type_arg, sys_var *var_arg,
88
 
                 const LEX_STRING *base_name_arg, Item *value_arg) :
89
 
  uint64_t_value(0),
90
 
  str_value(""),
91
 
  var(var_arg),
92
 
  type(type_arg),
93
 
  base(*base_name_arg)
94
 
{
95
 
  /*
96
 
    If the set value is a field, change it to a string to allow things like
97
 
    SET table_type=MYISAM;
98
 
  */
99
 
  if (value_arg && value_arg->type() == Item::FIELD_ITEM)
100
 
  {
101
 
    Item_field *item= (Item_field*) value_arg;
102
 
    if (!(value=new Item_string(item->field_name,
103
 
                                (uint32_t) strlen(item->field_name),
104
 
                                item->collation.collation)))
105
 
      value=value_arg;                  /* Give error message later */
106
 
  }
107
 
  else
108
 
  {
109
 
    value= value_arg;
110
 
  }
111
 
}
112
 
 
113
 
int set_var::check(Session *session)
114
 
{
115
 
  if (var->is_readonly())
116
 
  {
117
 
    my_error(ER_INCORRECT_GLOBAL_LOCAL_VAR, MYF(0), var->getName().c_str(), "read only");
118
 
    return -1;
119
 
  }
120
 
  if (var->check_type(type))
121
 
  {
122
 
    int err= type == OPT_GLOBAL ? ER_LOCAL_VARIABLE : ER_GLOBAL_VARIABLE;
123
 
    my_error(static_cast<drizzled::error_t>(err), MYF(0), var->getName().c_str());
124
 
    return -1;
125
 
  }
126
 
  /* value is a NULL pointer if we are using SET ... = DEFAULT */
127
 
  if (!value)
128
 
  {
129
 
    if (var->check_default(type))
130
 
    {
131
 
      my_error(ER_NO_DEFAULT, MYF(0), var->getName().c_str());
132
 
      return -1;
133
 
    }
134
 
    return 0;
135
 
  }
136
 
 
137
 
  if ((!value->fixed &&
138
 
       value->fix_fields(session, &value)) || value->check_cols(1))
139
 
    return -1;
140
 
  if (var->check_update_type(value->result_type()))
141
 
  {
142
 
    my_error(ER_WRONG_TYPE_FOR_VAR, MYF(0), var->getName().c_str());
143
 
    return -1;
144
 
  }
145
 
  return var->check(session, this) ? -1 : 0;
146
 
}
147
 
 
148
 
/**
149
 
  Update variable
150
 
 
151
 
  @param   session    thread handler
152
 
  @returns 0|1    ok or ERROR
153
 
 
154
 
  @note ERROR can be only due to abnormal operations involving
155
 
  the server's execution evironment such as
156
 
  out of memory, hard disk failure or the computer blows up.
157
 
  Consider set_var::check() method if there is a need to return
158
 
  an error due to logics.
159
 
*/
160
 
int set_var::update(Session *session)
161
 
{
162
 
  try
163
 
  {
164
 
    if (! value)
165
 
      var->set_default(session, type);
166
 
    else if (var->update(session, this))
167
 
      return -1;                                // should never happen
168
 
    if (var->getAfterUpdateTrigger())
169
 
      (*var->getAfterUpdateTrigger())(session, type);
170
 
  }
171
 
  catch (invalid_option_value &ex)
172
 
  {
173
 
    /* TODO: Fix this to be typesafe once we have properly typed set_var */
174
 
    string new_val= boost::lexical_cast<string>(uint64_t_value);
175
 
    if (boost::get_error_info<invalid_max_info>(ex) != NULL)
176
 
    { 
177
 
      const uint64_t max_val= *(boost::get_error_info<invalid_max_info>(ex));
178
 
      string explanation("(> ");
179
 
      explanation.append(boost::lexical_cast<std::string>(max_val));
180
 
      explanation.push_back(')');
181
 
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
182
 
                          ER_INVALID_OPTION_VALUE,
183
 
                          ER(ER_INVALID_OPTION_VALUE),
184
 
                          var->getName().c_str(),
185
 
                          new_val.c_str(),
186
 
                          explanation.c_str());
187
 
    }
188
 
    else if (boost::get_error_info<invalid_min_info>(ex) != NULL)
189
 
    { 
190
 
      const int64_t min_val= *(boost::get_error_info<invalid_min_info>(ex));
191
 
      string explanation("(< ");
192
 
      explanation.append(boost::lexical_cast<std::string>(min_val));
193
 
      explanation.push_back(')');
194
 
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
195
 
                          ER_INVALID_OPTION_VALUE,
196
 
                          ER(ER_INVALID_OPTION_VALUE),
197
 
                          var->getName().c_str(),
198
 
                          new_val.c_str(),
199
 
                          explanation.c_str());
200
 
    }
201
 
    else if (boost::get_error_info<invalid_value>(ex) != NULL)
202
 
    {
203
 
      const std::string str_val= *(boost::get_error_info<invalid_value>(ex));
204
 
      string explanation("(");
205
 
      explanation.append(str_val);
206
 
      explanation.push_back(')');
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
 
                          explanation.c_str());
213
 
    }
214
 
    else
215
 
    {
216
 
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
217
 
                          ER_INVALID_OPTION_VALUE,
218
 
                          ER(ER_INVALID_OPTION_VALUE),
219
 
                          var->getName().c_str(),
220
 
                          new_val.c_str(),
221
 
                          "");
222
 
    }
223
 
  }
224
 
  return 0;
225
 
}
226
 
 
227
 
/*****************************************************************************
228
 
  Functions to handle SET @user_variable=const_expr
229
 
*****************************************************************************/
230
 
 
231
 
int set_var_user::check(Session *session)
232
 
{
233
 
  /*
234
 
    Item_func_set_user_var can't substitute something else on its place =>
235
 
    0 can be passed as last argument (reference on item)
236
 
  */
237
 
  return (user_var_item->fix_fields(session, (Item**) 0) ||
238
 
          user_var_item->check(0)) ? -1 : 0;
239
 
}
240
 
 
241
 
 
242
 
int set_var_user::update(Session *)
243
 
{
244
 
  if (user_var_item->update())
245
 
  {
246
 
    /* Give an error if it's not given already */
247
 
    my_message(ER_SET_CONSTANTS_ONLY, ER(ER_SET_CONSTANTS_ONLY), MYF(0));
248
 
    return -1;
249
 
  }
250
 
  return 0;
251
 
}
252
 
 
253
 
void set_var::setValue(const std::string &new_value)
254
 
{
255
 
  str_value= new_value;
256
 
}
257
 
 
258
 
void set_var::setValue(uint64_t new_value)
259
 
{
260
 
  uint64_t_value= new_value;
261
 
}
262
 
 
263
 
void set_var::updateValue()
264
 
{
265
 
  if (var->show_type() != SHOW_CHAR)
266
 
  {
267
 
    uint64_t_value= value->val_int();
268
 
  }
269
 
}
270
 
 
271
 
 
272
 
} /* namespace drizzled */