~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/set_var.cc

  • Committer: Brian Aker
  • Date: 2010-11-19 19:42:44 UTC
  • mto: (1945.2.1 quick)
  • mto: This revision was merged to the branch mainline in revision 1944.
  • Revision ID: brian@tangent.org-20101119194244-7vx6u5vwzvu9uvex
Remove dead getShare() call which should have been a call on the cache
directly.

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
 
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 <string>
 
24
 
 
25
#include "drizzled/session.h"
 
26
#include "drizzled/item/string.h"
 
27
#include "drizzled/sql_list.h"
 
28
 
 
29
using namespace std;
 
30
 
 
31
namespace drizzled
 
32
{
 
33
 
 
34
/**
 
35
  Execute update of all variables.
 
36
 
 
37
  First run a check of all variables that all updates will go ok.
 
38
  If yes, then execute all updates, returning an error if any one failed.
 
39
 
 
40
  This should ensure that in all normal cases none all or variables are
 
41
  updated.
 
42
 
 
43
  @param Session                Thread id
 
44
  @param var_list       List of variables to update
 
45
 
 
46
  @retval
 
47
    0   ok
 
48
  @retval
 
49
    1   ERROR, message sent (normally no variables was updated)
 
50
  @retval
 
51
    -1  ERROR, message not sent
 
52
*/
 
53
 
 
54
int sql_set_variables(Session *session, List<set_var_base> *var_list)
 
55
{
 
56
  int error;
 
57
  List_iterator_fast<set_var_base> it(*var_list);
 
58
 
 
59
  set_var_base *var;
 
60
  while ((var=it++))
 
61
  {
 
62
    if ((error= var->check(session)))
 
63
      goto err;
 
64
  }
 
65
  if (!(error= test(session->is_error())))
 
66
  {
 
67
    it.rewind();
 
68
    while ((var= it++))
 
69
      error|= var->update(session);         // Returns 0, -1 or 1
 
70
  }
 
71
 
 
72
err:
 
73
  free_underlaid_joins(session, &session->lex->select_lex);
 
74
  return(error);
 
75
}
 
76
 
 
77
 
 
78
/*****************************************************************************
 
79
  Functions to handle SET mysql_internal_variable=const_expr
 
80
*****************************************************************************/
 
81
set_var::set_var(sql_var_t type_arg, sys_var *var_arg,
 
82
                 const LEX_STRING *base_name_arg, Item *value_arg) :
 
83
  var(var_arg), type(type_arg), base(*base_name_arg)
 
84
{
 
85
  /*
 
86
    If the set value is a field, change it to a string to allow things like
 
87
    SET table_type=MYISAM;
 
88
  */
 
89
  if (value_arg && value_arg->type() == Item::FIELD_ITEM)
 
90
  {
 
91
    Item_field *item= (Item_field*) value_arg;
 
92
    if (!(value=new Item_string(item->field_name,
 
93
                                (uint32_t) strlen(item->field_name),
 
94
                                item->collation.collation)))
 
95
      value=value_arg;                  /* Give error message later */
 
96
  }
 
97
  else
 
98
    value=value_arg;
 
99
}
 
100
 
 
101
int set_var::check(Session *session)
 
102
{
 
103
  if (var->is_readonly())
 
104
  {
 
105
    my_error(ER_INCORRECT_GLOBAL_LOCAL_VAR, MYF(0), var->getName().c_str(), "read only");
 
106
    return -1;
 
107
  }
 
108
  if (var->check_type(type))
 
109
  {
 
110
    int err= type == OPT_GLOBAL ? ER_LOCAL_VARIABLE : ER_GLOBAL_VARIABLE;
 
111
    my_error(err, MYF(0), var->getName().c_str());
 
112
    return -1;
 
113
  }
 
114
  /* value is a NULL pointer if we are using SET ... = DEFAULT */
 
115
  if (!value)
 
116
  {
 
117
    if (var->check_default(type))
 
118
    {
 
119
      my_error(ER_NO_DEFAULT, MYF(0), var->getName().c_str());
 
120
      return -1;
 
121
    }
 
122
    return 0;
 
123
  }
 
124
 
 
125
  if ((!value->fixed &&
 
126
       value->fix_fields(session, &value)) || value->check_cols(1))
 
127
    return -1;
 
128
  if (var->check_update_type(value->result_type()))
 
129
  {
 
130
    my_error(ER_WRONG_TYPE_FOR_VAR, MYF(0), var->getName().c_str());
 
131
    return -1;
 
132
  }
 
133
  return var->check(session, this) ? -1 : 0;
 
134
}
 
135
 
 
136
/**
 
137
  Update variable
 
138
 
 
139
  @param   session    thread handler
 
140
  @returns 0|1    ok or ERROR
 
141
 
 
142
  @note ERROR can be only due to abnormal operations involving
 
143
  the server's execution evironment such as
 
144
  out of memory, hard disk failure or the computer blows up.
 
145
  Consider set_var::check() method if there is a need to return
 
146
  an error due to logics.
 
147
*/
 
148
int set_var::update(Session *session)
 
149
{
 
150
  try
 
151
  {
 
152
    if (! value)
 
153
      var->set_default(session, type);
 
154
    else if (var->update(session, this))
 
155
      return -1;                                // should never happen
 
156
    if (var->getAfterUpdateTrigger())
 
157
      (*var->getAfterUpdateTrigger())(session, type);
 
158
  }
 
159
  catch (boost::exception &)
 
160
  {
 
161
    /* TODO: Fix this to be typesafe once we have properly typed set_var */
 
162
    string new_val= boost::lexical_cast<string>(save_result.uint32_t_value);
 
163
    push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
 
164
                        ER_TRUNCATED_WRONG_VALUE,
 
165
                        ER(ER_TRUNCATED_WRONG_VALUE), var->getName().c_str(),
 
166
                        new_val.c_str());
 
167
  }
 
168
  return 0;
 
169
}
 
170
 
 
171
/*****************************************************************************
 
172
  Functions to handle SET @user_variable=const_expr
 
173
*****************************************************************************/
 
174
 
 
175
int set_var_user::check(Session *session)
 
176
{
 
177
  /*
 
178
    Item_func_set_user_var can't substitute something else on its place =>
 
179
    0 can be passed as last argument (reference on item)
 
180
  */
 
181
  return (user_var_item->fix_fields(session, (Item**) 0) ||
 
182
          user_var_item->check(0)) ? -1 : 0;
 
183
}
 
184
 
 
185
 
 
186
int set_var_user::update(Session *)
 
187
{
 
188
  if (user_var_item->update())
 
189
  {
 
190
    /* Give an error if it's not given already */
 
191
    my_message(ER_SET_CONSTANTS_ONLY, ER(ER_SET_CONSTANTS_ONLY), MYF(0));
 
192
    return -1;
 
193
  }
 
194
  return 0;
 
195
}
 
196
 
 
197
} /* namespace drizzled */