~drizzle-trunk/drizzle/development

492.3.35 by Lee
more changes to move functions from item_func.cc/h to the functions directory
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.
492.3.35 by Lee
more changes to move functions from item_func.cc/h to the functions directory
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>
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
21
670.1.20 by Monty Taylor
Renamed functions to function... everything else is singular.
22
#include <drizzled/function/set_user_var.h>
584.5.1 by Monty Taylor
Removed field includes from field.h.
23
#include <drizzled/field/num.h>
584.1.15 by Monty Taylor
The mega-patch from hell. Renamed sql_class to session (since that's what it is) and removed it and field and table from common_includes.
24
#include <drizzled/session.h>
971.6.1 by Eric Day
Renamed Protocol to Client, cleaned up some unnecessary methods along the way.
25
#include <drizzled/plugin/client.h>
2154.2.24 by Brian Aker
Merge in all changes for current_session, etc.
26
#include <drizzled/user_var_entry.h>
2234.1.3 by Olaf van der Spek
Refactor includes
27
#include <drizzled/table.h>
492.3.35 by Lee
more changes to move functions from item_func.cc/h to the functions directory
28
2234.1.3 by Olaf van der Spek
Refactor includes
29
namespace drizzled {
971.3.65 by Eric Day
Namespace cleanup for Protocol and Listen.
30
492.3.35 by Lee
more changes to move functions from item_func.cc/h to the functions directory
31
/*
32
  When a user variable is updated (in a SET command or a query like
33
  SELECT @a:= ).
34
*/
35
36
bool Item_func_set_user_var::fix_fields(Session *session, Item **ref)
37
{
38
  assert(fixed == 0);
39
  /* fix_fields will call Item_func_set_user_var::fix_length_and_dec */
40
  if (Item_func::fix_fields(session, ref) ||
995 by Brian Aker
Refactor get_variable to session
41
      !(entry= session->getVariable(name, true)))
492.3.35 by Lee
more changes to move functions from item_func.cc/h to the functions directory
42
    return true;
43
  /*
44
     Remember the last query which updated it, this way a query can later know
45
     if this variable is a constant item in the query (it is if update_query_id
46
     is different from query_id).
47
  */
1273.1.1 by Jay Pipes
* Changes Session::warn_id to Session::warn_query_id
48
  entry->update_query_id= session->getQueryId();
492.3.35 by Lee
more changes to move functions from item_func.cc/h to the functions directory
49
  /*
50
    As it is wrong and confusing to associate any
51
    character set with NULL, @a should be latin2
52
    after this query sequence:
53
54
      SET @a=_latin2'string';
55
      SET @a=NULL;
56
57
    I.e. the second query should not change the charset
58
    to the current default value, but should keep the
59
    original value assigned during the first query.
60
    In order to do it, we don't copy charset
61
    from the argument if the argument is NULL
62
    and the variable has previously been initialized.
63
  */
64
  null_item= (args[0]->type() == NULL_ITEM);
65
  if (!entry->collation.collation || !null_item)
66
    entry->collation.set(args[0]->collation.collation, DERIVATION_IMPLICIT);
67
  collation.set(entry->collation.collation, DERIVATION_IMPLICIT);
68
  cached_result_type= args[0]->result_type();
69
  return false;
70
}
71
72
void
73
Item_func_set_user_var::fix_length_and_dec()
74
{
75
  maybe_null=args[0]->maybe_null;
76
  max_length=args[0]->max_length;
77
  decimals=args[0]->decimals;
78
  collation.set(args[0]->collation.collation, DERIVATION_IMPLICIT);
79
}
80
81
/*
82
  Mark field in read_map
83
84
  NOTES
85
    This is used by filesort to register used fields in a a temporary
86
    column read set or to register used fields in a view
87
*/
88
89
bool Item_func_set_user_var::register_field_in_read_map(unsigned char *arg)
90
{
91
  if (result_field)
92
  {
93
    Table *table= (Table *) arg;
1660.1.3 by Brian Aker
Encapsulate Table in field
94
    if (result_field->getTable() == table || !table)
1999.4.2 by Brian Aker
Encapsulate the field's position.
95
      result_field->getTable()->setReadSet(result_field->position());
492.3.35 by Lee
more changes to move functions from item_func.cc/h to the functions directory
96
  }
97
  return 0;
98
}
99
100
2246.3.5 by Olaf van der Spek
Propogate return void
101
void
492.3.35 by Lee
more changes to move functions from item_func.cc/h to the functions directory
102
Item_func_set_user_var::update_hash(void *ptr, uint32_t length,
103
                                    Item_result res_type,
2254 by Brian Aker
Shift CHARSET_INFO to charset_info_st
104
                                    const charset_info_st * const cs, Derivation dv,
492.3.35 by Lee
more changes to move functions from item_func.cc/h to the functions directory
105
                                    bool unsigned_arg)
106
{
107
  /*
108
    If we set a variable explicitely to NULL then keep the old
109
    result type of the variable
110
  */
111
  if ((null_value= args[0]->null_value) && null_item)
112
    res_type= entry->type;                      // Don't change type of item
2246.3.4 by Olaf van der Spek
Propogate return void
113
  entry->update_hash((null_value= args[0]->null_value), ptr, length, res_type, cs, dv, unsigned_arg);
492.3.35 by Lee
more changes to move functions from item_func.cc/h to the functions directory
114
}
115
116
/**
117
  This functions is invoked on SET \@variable or
118
  \@variable:= expression.
119
120
  Evaluate (and check expression), store results.
121
122
  @note
123
    For now it always return OK. All problem with value evaluating
124
    will be caught by session->is_error() check in sql_set_variables().
125
126
  @retval
127
    false OK.
128
*/
129
130
bool
131
Item_func_set_user_var::check(bool use_result_field)
132
{
133
  if (use_result_field && !result_field)
134
    use_result_field= false;
135
136
  switch (cached_result_type) {
137
  case REAL_RESULT:
2008 by Brian Aker
Formatting + remove default from switch/case.
138
    {
139
      save_result.vreal= use_result_field ? result_field->val_real() :
140
        args[0]->val_real();
141
      break;
142
    }
492.3.35 by Lee
more changes to move functions from item_func.cc/h to the functions directory
143
  case INT_RESULT:
2008 by Brian Aker
Formatting + remove default from switch/case.
144
    {
145
      save_result.vint= use_result_field ? result_field->val_int() :
146
        args[0]->val_int();
147
      unsigned_flag= use_result_field ? ((Field_num*)result_field)->unsigned_flag:
148
        args[0]->unsigned_flag;
149
      break;
150
    }
492.3.35 by Lee
more changes to move functions from item_func.cc/h to the functions directory
151
  case STRING_RESULT:
2008 by Brian Aker
Formatting + remove default from switch/case.
152
    {
153
      save_result.vstr= use_result_field ? result_field->val_str_internal(&value) :
154
        args[0]->val_str(&value);
155
      break;
156
    }
492.3.35 by Lee
more changes to move functions from item_func.cc/h to the functions directory
157
  case DECIMAL_RESULT:
2008 by Brian Aker
Formatting + remove default from switch/case.
158
    {
159
      save_result.vdec= use_result_field ?
160
        result_field->val_decimal(&decimal_buff) :
161
        args[0]->val_decimal(&decimal_buff);
162
      break;
163
    }
492.3.35 by Lee
more changes to move functions from item_func.cc/h to the functions directory
164
  case ROW_RESULT:
165
    // This case should never be chosen
166
    assert(0);
167
    break;
168
  }
2008 by Brian Aker
Formatting + remove default from switch/case.
169
170
  return false;
492.3.35 by Lee
more changes to move functions from item_func.cc/h to the functions directory
171
}
172
173
/**
174
  This functions is invoked on
175
  SET \@variable or \@variable:= expression.
176
177
  @note
178
    We have to store the expression as such in the variable, independent of
179
    the value method used by the user
180
181
  @retval
182
    0   OK
183
  @retval
184
    1   EOM Error
185
186
*/
187
2246.3.5 by Olaf van der Spek
Propogate return void
188
void
492.3.35 by Lee
more changes to move functions from item_func.cc/h to the functions directory
189
Item_func_set_user_var::update()
190
{
191
  switch (cached_result_type) {
192
  case REAL_RESULT:
2008 by Brian Aker
Formatting + remove default from switch/case.
193
    {
2246.3.5 by Olaf van der Spek
Propogate return void
194
      update_hash((void*) &save_result.vreal,sizeof(save_result.vreal),
2008 by Brian Aker
Formatting + remove default from switch/case.
195
                       REAL_RESULT, &my_charset_bin, DERIVATION_IMPLICIT, 0);
196
      break;
197
    }
198
492.3.35 by Lee
more changes to move functions from item_func.cc/h to the functions directory
199
  case INT_RESULT:
2008 by Brian Aker
Formatting + remove default from switch/case.
200
    {
2246.3.5 by Olaf van der Spek
Propogate return void
201
      update_hash((void*) &save_result.vint, sizeof(save_result.vint),
2008 by Brian Aker
Formatting + remove default from switch/case.
202
                       INT_RESULT, &my_charset_bin, DERIVATION_IMPLICIT,
203
                       unsigned_flag);
204
      break;
205
    }
206
492.3.35 by Lee
more changes to move functions from item_func.cc/h to the functions directory
207
  case STRING_RESULT:
2008 by Brian Aker
Formatting + remove default from switch/case.
208
    {
209
      if (!save_result.vstr)                                      // Null value
2246.3.5 by Olaf van der Spek
Propogate return void
210
        update_hash((void*) 0, 0, STRING_RESULT, &my_charset_bin,
2008 by Brian Aker
Formatting + remove default from switch/case.
211
                         DERIVATION_IMPLICIT, 0);
212
      else
2246.3.5 by Olaf van der Spek
Propogate return void
213
        update_hash((void*) save_result.vstr->ptr(),
2008 by Brian Aker
Formatting + remove default from switch/case.
214
                         save_result.vstr->length(), STRING_RESULT,
215
                         save_result.vstr->charset(),
216
                         DERIVATION_IMPLICIT, 0);
217
      break;
218
    }
219
492.3.35 by Lee
more changes to move functions from item_func.cc/h to the functions directory
220
  case DECIMAL_RESULT:
2008 by Brian Aker
Formatting + remove default from switch/case.
221
    {
222
      if (!save_result.vdec)                                      // Null value
2246.3.5 by Olaf van der Spek
Propogate return void
223
        update_hash((void*) 0, 0, DECIMAL_RESULT, &my_charset_bin,
2008 by Brian Aker
Formatting + remove default from switch/case.
224
                         DERIVATION_IMPLICIT, 0);
225
      else
2246.3.5 by Olaf van der Spek
Propogate return void
226
        update_hash((void*) save_result.vdec,
2030.1.4 by Brian Aker
Change my_decimal to Decimal
227
                         sizeof(type::Decimal), DECIMAL_RESULT,
2008 by Brian Aker
Formatting + remove default from switch/case.
228
                         &my_charset_bin, DERIVATION_IMPLICIT, 0);
229
      break;
230
    }
231
492.3.35 by Lee
more changes to move functions from item_func.cc/h to the functions directory
232
  case ROW_RESULT:
233
    // This case should never be chosen
234
    assert(0);
235
    break;
236
  }
237
}
238
239
double Item_func_set_user_var::val_real()
240
{
241
  assert(fixed == 1);
242
  check(0);
243
  update();                                     // Store expression
244
  return entry->val_real(&null_value);
245
}
246
247
int64_t Item_func_set_user_var::val_int()
248
{
249
  assert(fixed == 1);
250
  check(0);
251
  update();                                     // Store expression
252
  return entry->val_int(&null_value);
253
}
254
255
String *Item_func_set_user_var::val_str(String *str)
256
{
257
  assert(fixed == 1);
258
  check(0);
259
  update();                                     // Store expression
260
  return entry->val_str(&null_value, str, decimals);
261
}
262
263
2030.1.4 by Brian Aker
Change my_decimal to Decimal
264
type::Decimal *Item_func_set_user_var::val_decimal(type::Decimal *val)
492.3.35 by Lee
more changes to move functions from item_func.cc/h to the functions directory
265
{
266
  assert(fixed == 1);
267
  check(0);
268
  update();                                     // Store expression
269
  return entry->val_decimal(&null_value, val);
270
}
271
272
double Item_func_set_user_var::val_result()
273
{
274
  assert(fixed == 1);
275
  check(true);
276
  update();                                     // Store expression
277
  return entry->val_real(&null_value);
278
}
279
280
int64_t Item_func_set_user_var::val_int_result()
281
{
282
  assert(fixed == 1);
283
  check(true);
284
  update();                                     // Store expression
285
  return entry->val_int(&null_value);
286
}
287
288
String *Item_func_set_user_var::str_result(String *str)
289
{
290
  assert(fixed == 1);
291
  check(true);
292
  update();                                     // Store expression
293
  return entry->val_str(&null_value, str, decimals);
294
}
295
296
2030.1.4 by Brian Aker
Change my_decimal to Decimal
297
type::Decimal *Item_func_set_user_var::val_decimal_result(type::Decimal *val)
492.3.35 by Lee
more changes to move functions from item_func.cc/h to the functions directory
298
{
299
  assert(fixed == 1);
300
  check(true);
301
  update();                                     // Store expression
302
  return entry->val_decimal(&null_value, val);
303
}
304
2215.2.1 by Stewart Smith
remove enum_query_type which was effectively unused. It was set to one value once, compared to it once (i.e. always true) and passed around everywhere doing nothing.
305
void Item_func_set_user_var::print(String *str)
492.3.35 by Lee
more changes to move functions from item_func.cc/h to the functions directory
306
{
307
  str->append(STRING_WITH_LEN("(@"));
308
  str->append(name.str, name.length);
309
  str->append(STRING_WITH_LEN(":="));
2215.2.1 by Stewart Smith
remove enum_query_type which was effectively unused. It was set to one value once, compared to it once (i.e. always true) and passed around everywhere doing nothing.
310
  args[0]->print(str);
492.3.35 by Lee
more changes to move functions from item_func.cc/h to the functions directory
311
  str->append(')');
312
}
313
971.6.1 by Eric Day
Renamed Protocol to Client, cleaned up some unnecessary methods along the way.
314
bool Item_func_set_user_var::send(plugin::Client *client, String *str_arg)
492.3.35 by Lee
more changes to move functions from item_func.cc/h to the functions directory
315
{
316
  if (result_field)
317
  {
318
    check(1);
319
    update();
971.6.1 by Eric Day
Renamed Protocol to Client, cleaned up some unnecessary methods along the way.
320
    return client->store(result_field);
492.3.35 by Lee
more changes to move functions from item_func.cc/h to the functions directory
321
  }
971.6.1 by Eric Day
Renamed Protocol to Client, cleaned up some unnecessary methods along the way.
322
  return Item::send(client, str_arg);
492.3.35 by Lee
more changes to move functions from item_func.cc/h to the functions directory
323
}
324
1052.2.4 by Nathan Williams
No actual code changes. Changed Send_field to SendField to be consistent with coding standards.
325
void Item_func_set_user_var::make_field(SendField *tmp_field)
492.3.35 by Lee
more changes to move functions from item_func.cc/h to the functions directory
326
{
327
  if (result_field)
328
  {
329
    result_field->make_field(tmp_field);
330
    assert(tmp_field->table_name != 0);
331
    if (Item::name)
332
      tmp_field->col_name=Item::name;               // Use user supplied name
333
  }
334
  else
2008.2.3 by Brian Aker
Fixing up a, somewhat, hidden unsigned type to solve a few issues around
335
  {
492.3.35 by Lee
more changes to move functions from item_func.cc/h to the functions directory
336
    Item::make_field(tmp_field);
2008.2.3 by Brian Aker
Fixing up a, somewhat, hidden unsigned type to solve a few issues around
337
  }
492.3.35 by Lee
more changes to move functions from item_func.cc/h to the functions directory
338
}
339
340
/*
341
  Save the value of a user variable into a field
342
343
  SYNOPSIS
344
    save_in_field()
345
      field           target field to save the value to
346
      no_conversion   flag indicating whether conversions are allowed
347
348
  DESCRIPTION
349
    Save the function value into a field and update the user variable
350
    accordingly. If a result field is defined and the target field doesn't
351
    coincide with it then the value from the result field will be used as
352
    the new value of the user variable.
353
354
    The reason to have this method rather than simply using the result
355
    field in the val_xxx() methods is that the value from the result field
356
    not always can be used when the result field is defined.
357
    Let's consider the following cases:
358
    1) when filling a tmp table the result field is defined but the value of it
359
    is undefined because it has to be produced yet. Thus we can't use it.
360
    2) on execution of an INSERT ... SELECT statement the save_in_field()
361
    function will be called to fill the data in the new record. If the SELECT
362
    part uses a tmp table then the result field is defined and should be
363
    used in order to get the correct result.
364
365
    The difference between the SET_USER_VAR function and regular functions
366
    like CONCAT is that the Item_func objects for the regular functions are
367
    replaced by Item_field objects after the values of these functions have
368
    been stored in a tmp table. Yet an object of the Item_field class cannot
369
    be used to update a user variable.
370
    Due to this we have to handle the result field in a special way here and
371
    in the Item_func_set_user_var::send() function.
372
373
  RETURN VALUES
374
    false       Ok
375
    true        Error
376
*/
377
378
int Item_func_set_user_var::save_in_field(Field *field, bool no_conversions,
379
                                          bool can_use_result_field)
380
{
381
  bool use_result_field= (!can_use_result_field ? 0 :
382
                          (result_field && result_field != field));
383
  int error;
384
385
  /* Update the value of the user variable */
386
  check(use_result_field);
387
  update();
388
389
  if (result_type() == STRING_RESULT ||
390
      (result_type() == REAL_RESULT && field->result_type() == STRING_RESULT))
391
  {
392
    String *result;
2254 by Brian Aker
Shift CHARSET_INFO to charset_info_st
393
    const charset_info_st * const cs= collation.collation;
492.3.35 by Lee
more changes to move functions from item_func.cc/h to the functions directory
394
    char buff[MAX_FIELD_WIDTH];         // Alloc buffer for small columns
395
    str_value.set_quick(buff, sizeof(buff), cs);
396
    result= entry->val_str(&null_value, &str_value, decimals);
397
398
    if (null_value)
399
    {
400
      str_value.set_quick(0, 0, cs);
401
      return set_field_to_null_with_conversions(field, no_conversions);
402
    }
403
404
    /* NOTE: If null_value == false, "result" must be not NULL.  */
405
406
    field->set_notnull();
407
    error=field->store(result->ptr(),result->length(),cs);
408
    str_value.set_quick(0, 0, cs);
409
  }
410
  else if (result_type() == REAL_RESULT)
411
  {
412
    double nr= entry->val_real(&null_value);
413
    if (null_value)
414
      return set_field_to_null(field);
415
    field->set_notnull();
416
    error=field->store(nr);
417
  }
418
  else if (result_type() == DECIMAL_RESULT)
419
  {
2030.1.4 by Brian Aker
Change my_decimal to Decimal
420
    type::Decimal decimal_value;
421
    type::Decimal *val= entry->val_decimal(&null_value, &decimal_value);
492.3.35 by Lee
more changes to move functions from item_func.cc/h to the functions directory
422
    if (null_value)
423
      return set_field_to_null(field);
424
    field->set_notnull();
425
    error=field->store_decimal(val);
426
  }
427
  else
428
  {
429
    int64_t nr= entry->val_int(&null_value);
430
    if (null_value)
431
      return set_field_to_null_with_conversions(field, no_conversions);
432
    field->set_notnull();
433
    error=field->store(nr, unsigned_flag);
434
  }
435
  return error;
436
}
437
438
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
439
} /* namespace drizzled */