~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
2173.2.1 by Monty Taylor
Fixes incorrect usage of include
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
2173.2.1 by Monty Taylor
Fixes incorrect usage of include
26
#include <drizzled/session.h>
27
#include <drizzled/item/string.h>
28
#include <drizzled/sql_list.h>
2154.2.24 by Brian Aker
Merge in all changes for current_session, etc.
29
#include <drizzled/function/set_user_var.h>
1878.3.1 by Monty Taylor
Split set_var.* into sys_var.* and set_var.*
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
2040.6.4 by Monty Taylor
Replaced List<set_var_base> with
56
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.*
57
{
58
  int error;
2040.6.4 by Monty Taylor
Replaced List<set_var_base> with
59
60
  SetVarVector::const_iterator it(var_list.begin());
61
62
  while (it != var_list.end())
1878.3.1 by Monty Taylor
Split set_var.* into sys_var.* and set_var.*
63
  {
2040.6.4 by Monty Taylor
Replaced List<set_var_base> with
64
    if ((error= (*it)->check(session)))
1878.3.1 by Monty Taylor
Split set_var.* into sys_var.* and set_var.*
65
      goto err;
2040.6.4 by Monty Taylor
Replaced List<set_var_base> with
66
    ++it;
1878.3.1 by Monty Taylor
Split set_var.* into sys_var.* and set_var.*
67
  }
68
  if (!(error= test(session->is_error())))
69
  {
2040.6.4 by Monty Taylor
Replaced List<set_var_base> with
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
    }
1878.3.1 by Monty Taylor
Split set_var.* into sys_var.* and set_var.*
76
  }
77
78
err:
2187.2.2 by Brian Aker
getLex() usage and fix for table_name creation during admin commands.
79
  free_underlaid_joins(session, &session->getLex()->select_lex);
1878.3.1 by Monty Taylor
Split set_var.* into sys_var.* and set_var.*
80
  return(error);
81
}
82
83
84
/*****************************************************************************
85
  Functions to handle SET mysql_internal_variable=const_expr
86
*****************************************************************************/
1878.3.2 by Monty Taylor
Split out show_type into its own header and made sys_var work through
87
set_var::set_var(sql_var_t type_arg, sys_var *var_arg,
88
                 const LEX_STRING *base_name_arg, Item *value_arg) :
2070.2.2 by Monty Taylor
Removed some guts from set_var.
89
  uint64_t_value(0),
90
  str_value(""),
91
  var(var_arg),
92
  type(type_arg),
93
  base(*base_name_arg)
1878.3.2 by Monty Taylor
Split out show_type into its own header and made sys_var work through
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
2070.2.2 by Monty Taylor
Removed some guts from set_var.
108
  {
109
    value= value_arg;
110
  }
1878.3.2 by Monty Taylor
Split out show_type into its own header and made sys_var work through
111
}
1878.3.1 by Monty Taylor
Split set_var.* into sys_var.* and set_var.*
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;
2054.1.2 by Brian Aker
Rename of the Loooongggggg error type over to simply drizzled::error_t
123
    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.*
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
{
1897.4.14 by Monty Taylor
Update to support default values and properly throw warnings on value
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
  }
1964.1.4 by Monty Taylor
Use boost::exception data bundling instead of co-opting the exceptions
171
  catch (invalid_option_value &ex)
1897.4.14 by Monty Taylor
Update to support default values and properly throw warnings on value
172
  {
1897.4.18 by Monty Taylor
Cleaned up another debugging leftover.
173
    /* 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.
174
    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.
175
    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
176
    { 
1964.1.5 by Monty Taylor
Change how we deal with error_info, because on karmic it's returning a shared_ptr. Sigh.
177
      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
178
      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.
179
      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
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
    }
1964.1.5 by Monty Taylor
Change how we deal with error_info, because on karmic it's returning a shared_ptr. Sigh.
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));
1964.1.4 by Monty Taylor
Use boost::exception data bundling instead of co-opting the exceptions
191
      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.
192
      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
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
    }
2070.2.1 by Monty Taylor
First step in getting that anonymous union out of set_var.
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
    }
1964.1.4 by Monty Taylor
Use boost::exception data bundling instead of co-opting the exceptions
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
    }
1897.4.14 by Monty Taylor
Update to support default values and properly throw warnings on value
223
  }
1878.3.1 by Monty Taylor
Split set_var.* into sys_var.* and set_var.*
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
2070.2.1 by Monty Taylor
First step in getting that anonymous union out of set_var.
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
{
2070.2.2 by Monty Taylor
Removed some guts from set_var.
260
  uint64_t_value= new_value;
2070.2.1 by Monty Taylor
First step in getting that anonymous union out of set_var.
261
}
262
263
void set_var::updateValue()
264
{
2070.2.2 by Monty Taylor
Removed some guts from set_var.
265
  if (var->show_type() != SHOW_CHAR)
266
  {
267
    uint64_t_value= value->val_int();
268
  }
2070.2.1 by Monty Taylor
First step in getting that anonymous union out of set_var.
269
}
270
271
1878.3.1 by Monty Taylor
Split set_var.* into sys_var.* and set_var.*
272
} /* namespace drizzled */