~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
55
int sql_set_variables(Session *session, List<set_var_base> *var_list)
56
{
57
  int error;
58
  List_iterator_fast<set_var_base> it(*var_list);
59
60
  set_var_base *var;
61
  while ((var=it++))
62
  {
63
    if ((error= var->check(session)))
64
      goto err;
65
  }
66
  if (!(error= test(session->is_error())))
67
  {
68
    it.rewind();
69
    while ((var= it++))
70
      error|= var->update(session);         // Returns 0, -1 or 1
71
  }
72
73
err:
74
  free_underlaid_joins(session, &session->lex->select_lex);
75
  return(error);
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) :
84
  var(var_arg), type(type_arg), base(*base_name_arg)
85
{
86
  /*
87
    If the set value is a field, change it to a string to allow things like
88
    SET table_type=MYISAM;
89
  */
90
  if (value_arg && value_arg->type() == Item::FIELD_ITEM)
91
  {
92
    Item_field *item= (Item_field*) value_arg;
93
    if (!(value=new Item_string(item->field_name,
94
                                (uint32_t) strlen(item->field_name),
95
                                item->collation.collation)))
96
      value=value_arg;			/* Give error message later */
97
  }
98
  else
99
    value=value_arg;
100
}
1878.3.1 by Monty Taylor
Split set_var.* into sys_var.* and set_var.*
101
102
int set_var::check(Session *session)
103
{
104
  if (var->is_readonly())
105
  {
106
    my_error(ER_INCORRECT_GLOBAL_LOCAL_VAR, MYF(0), var->getName().c_str(), "read only");
107
    return -1;
108
  }
109
  if (var->check_type(type))
110
  {
111
    int err= type == OPT_GLOBAL ? ER_LOCAL_VARIABLE : ER_GLOBAL_VARIABLE;
112
    my_error(err, MYF(0), var->getName().c_str());
113
    return -1;
114
  }
115
  /* value is a NULL pointer if we are using SET ... = DEFAULT */
116
  if (!value)
117
  {
118
    if (var->check_default(type))
119
    {
120
      my_error(ER_NO_DEFAULT, MYF(0), var->getName().c_str());
121
      return -1;
122
    }
123
    return 0;
124
  }
125
126
  if ((!value->fixed &&
127
       value->fix_fields(session, &value)) || value->check_cols(1))
128
    return -1;
129
  if (var->check_update_type(value->result_type()))
130
  {
131
    my_error(ER_WRONG_TYPE_FOR_VAR, MYF(0), var->getName().c_str());
132
    return -1;
133
  }
134
  return var->check(session, this) ? -1 : 0;
135
}
136
137
/**
138
  Update variable
139
140
  @param   session    thread handler
141
  @returns 0|1    ok or	ERROR
142
143
  @note ERROR can be only due to abnormal operations involving
144
  the server's execution evironment such as
145
  out of memory, hard disk failure or the computer blows up.
146
  Consider set_var::check() method if there is a need to return
147
  an error due to logics.
148
*/
149
int set_var::update(Session *session)
150
{
1897.4.14 by Monty Taylor
Update to support default values and properly throw warnings on value
151
  try
152
  {
153
    if (! value)
154
      var->set_default(session, type);
155
    else if (var->update(session, this))
156
      return -1;				// should never happen
157
    if (var->getAfterUpdateTrigger())
158
      (*var->getAfterUpdateTrigger())(session, type);
159
  }
1964.1.4 by Monty Taylor
Use boost::exception data bundling instead of co-opting the exceptions
160
  catch (invalid_option_value &ex)
1897.4.14 by Monty Taylor
Update to support default values and properly throw warnings on value
161
  {
1897.4.18 by Monty Taylor
Cleaned up another debugging leftover.
162
    /* TODO: Fix this to be typesafe once we have properly typed set_var */
1897.4.14 by Monty Taylor
Update to support default values and properly throw warnings on value
163
    string new_val= boost::lexical_cast<string>(save_result.uint32_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.
164
    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
165
    { 
1964.1.5 by Monty Taylor
Change how we deal with error_info, because on karmic it's returning a shared_ptr. Sigh.
166
      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
167
      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.
168
      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
169
      explanation.push_back(')');
170
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
171
                          ER_INVALID_OPTION_VALUE,
172
                          ER(ER_INVALID_OPTION_VALUE),
173
                          var->getName().c_str(),
174
                          new_val.c_str(),
175
                          explanation.c_str());
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
    else if (boost::get_error_info<invalid_min_info>(ex) != NULL)
178
    { 
179
      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
180
      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.
181
      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
182
      explanation.push_back(')');
183
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
184
                          ER_INVALID_OPTION_VALUE,
185
                          ER(ER_INVALID_OPTION_VALUE),
186
                          var->getName().c_str(),
187
                          new_val.c_str(),
188
                          explanation.c_str());
189
    }
190
    else
191
    {
192
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
193
                          ER_INVALID_OPTION_VALUE,
194
                          ER(ER_INVALID_OPTION_VALUE),
195
                          var->getName().c_str(),
196
                          new_val.c_str(),
197
                          "");
198
    }
1897.4.14 by Monty Taylor
Update to support default values and properly throw warnings on value
199
  }
1878.3.1 by Monty Taylor
Split set_var.* into sys_var.* and set_var.*
200
  return 0;
201
}
202
203
/*****************************************************************************
204
  Functions to handle SET @user_variable=const_expr
205
*****************************************************************************/
206
207
int set_var_user::check(Session *session)
208
{
209
  /*
210
    Item_func_set_user_var can't substitute something else on its place =>
211
    0 can be passed as last argument (reference on item)
212
  */
213
  return (user_var_item->fix_fields(session, (Item**) 0) ||
214
	  user_var_item->check(0)) ? -1 : 0;
215
}
216
217
218
int set_var_user::update(Session *)
219
{
220
  if (user_var_item->update())
221
  {
222
    /* Give an error if it's not given already */
223
    my_message(ER_SET_CONSTANTS_ONLY, ER(ER_SET_CONSTANTS_ONLY), MYF(0));
224
    return -1;
225
  }
226
  return 0;
227
}
228
229
} /* namespace drizzled */