~drizzle-trunk/drizzle/development

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