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