1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
4
* Copyright (C) 2008 Sun Microsystems
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.
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.
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
20
#include <drizzled/server_includes.h>
22
#include <drizzled/functions/set_user_var.h>
25
When a user variable is updated (in a SET command or a query like
29
bool Item_func_set_user_var::fix_fields(Session *session, Item **ref)
32
/* fix_fields will call Item_func_set_user_var::fix_length_and_dec */
33
if (Item_func::fix_fields(session, ref) ||
34
!(entry= get_variable(&session->user_vars, name, 1)))
37
Remember the last query which updated it, this way a query can later know
38
if this variable is a constant item in the query (it is if update_query_id
39
is different from query_id).
41
entry->update_query_id= session->query_id;
43
As it is wrong and confusing to associate any
44
character set with NULL, @a should be latin2
45
after this query sequence:
47
SET @a=_latin2'string';
50
I.e. the second query should not change the charset
51
to the current default value, but should keep the
52
original value assigned during the first query.
53
In order to do it, we don't copy charset
54
from the argument if the argument is NULL
55
and the variable has previously been initialized.
57
null_item= (args[0]->type() == NULL_ITEM);
58
if (!entry->collation.collation || !null_item)
59
entry->collation.set(args[0]->collation.collation, DERIVATION_IMPLICIT);
60
collation.set(entry->collation.collation, DERIVATION_IMPLICIT);
61
cached_result_type= args[0]->result_type();
66
Item_func_set_user_var::fix_length_and_dec()
68
maybe_null=args[0]->maybe_null;
69
max_length=args[0]->max_length;
70
decimals=args[0]->decimals;
71
collation.set(args[0]->collation.collation, DERIVATION_IMPLICIT);
75
Mark field in read_map
78
This is used by filesort to register used fields in a a temporary
79
column read set or to register used fields in a view
82
bool Item_func_set_user_var::register_field_in_read_map(unsigned char *arg)
86
Table *table= (Table *) arg;
87
if (result_field->table == table || !table)
88
bitmap_set_bit(result_field->table->read_set, result_field->field_index);
89
if (result_field->vcol_info && result_field->vcol_info->expr_item)
90
return result_field->vcol_info->
91
expr_item->walk(&Item::register_field_in_read_map, 1, arg);
97
Mark field in bitmap supplied as *arg
101
bool Item_func_set_user_var::register_field_in_bitmap(unsigned char *arg)
103
MY_BITMAP *bitmap = (MY_BITMAP *) arg;
107
bitmap_set_bit(bitmap, result_field->field_index);
113
Item_func_set_user_var::update_hash(void *ptr, uint32_t length,
114
Item_result res_type,
115
const CHARSET_INFO * const cs, Derivation dv,
119
If we set a variable explicitely to NULL then keep the old
120
result type of the variable
122
if ((null_value= args[0]->null_value) && null_item)
123
res_type= entry->type; // Don't change type of item
124
if (::update_hash(entry, (null_value= args[0]->null_value),
125
ptr, length, res_type, cs, dv, unsigned_arg))
134
This functions is invoked on SET \@variable or
135
\@variable:= expression.
137
Evaluate (and check expression), store results.
140
For now it always return OK. All problem with value evaluating
141
will be caught by session->is_error() check in sql_set_variables().
148
Item_func_set_user_var::check(bool use_result_field)
150
if (use_result_field && !result_field)
151
use_result_field= false;
153
switch (cached_result_type) {
156
save_result.vreal= use_result_field ? result_field->val_real() :
162
save_result.vint= use_result_field ? result_field->val_int() :
164
unsigned_flag= use_result_field ? ((Field_num*)result_field)->unsigned_flag:
165
args[0]->unsigned_flag;
170
save_result.vstr= use_result_field ? result_field->val_str(&value) :
171
args[0]->val_str(&value);
176
save_result.vdec= use_result_field ?
177
result_field->val_decimal(&decimal_buff) :
178
args[0]->val_decimal(&decimal_buff);
183
// This case should never be chosen
191
This functions is invoked on
192
SET \@variable or \@variable:= expression.
195
We have to store the expression as such in the variable, independent of
196
the value method used by the user
206
Item_func_set_user_var::update()
210
switch (cached_result_type) {
213
res= update_hash((void*) &save_result.vreal,sizeof(save_result.vreal),
214
REAL_RESULT, &my_charset_bin, DERIVATION_IMPLICIT, 0);
219
res= update_hash((void*) &save_result.vint, sizeof(save_result.vint),
220
INT_RESULT, &my_charset_bin, DERIVATION_IMPLICIT,
226
if (!save_result.vstr) // Null value
227
res= update_hash((void*) 0, 0, STRING_RESULT, &my_charset_bin,
228
DERIVATION_IMPLICIT, 0);
230
res= update_hash((void*) save_result.vstr->ptr(),
231
save_result.vstr->length(), STRING_RESULT,
232
save_result.vstr->charset(),
233
DERIVATION_IMPLICIT, 0);
238
if (!save_result.vdec) // Null value
239
res= update_hash((void*) 0, 0, DECIMAL_RESULT, &my_charset_bin,
240
DERIVATION_IMPLICIT, 0);
242
res= update_hash((void*) save_result.vdec,
243
sizeof(my_decimal), DECIMAL_RESULT,
244
&my_charset_bin, DERIVATION_IMPLICIT, 0);
249
// This case should never be chosen
256
double Item_func_set_user_var::val_real()
260
update(); // Store expression
261
return entry->val_real(&null_value);
264
int64_t Item_func_set_user_var::val_int()
268
update(); // Store expression
269
return entry->val_int(&null_value);
272
String *Item_func_set_user_var::val_str(String *str)
276
update(); // Store expression
277
return entry->val_str(&null_value, str, decimals);
281
my_decimal *Item_func_set_user_var::val_decimal(my_decimal *val)
285
update(); // Store expression
286
return entry->val_decimal(&null_value, val);
289
double Item_func_set_user_var::val_result()
293
update(); // Store expression
294
return entry->val_real(&null_value);
297
int64_t Item_func_set_user_var::val_int_result()
301
update(); // Store expression
302
return entry->val_int(&null_value);
305
String *Item_func_set_user_var::str_result(String *str)
309
update(); // Store expression
310
return entry->val_str(&null_value, str, decimals);
314
my_decimal *Item_func_set_user_var::val_decimal_result(my_decimal *val)
318
update(); // Store expression
319
return entry->val_decimal(&null_value, val);
322
void Item_func_set_user_var::print(String *str, enum_query_type query_type)
324
str->append(STRING_WITH_LEN("(@"));
325
str->append(name.str, name.length);
326
str->append(STRING_WITH_LEN(":="));
327
args[0]->print(str, query_type);
332
void Item_func_set_user_var::print_as_stmt(String *str,
333
enum_query_type query_type)
335
str->append(STRING_WITH_LEN("set @"));
336
str->append(name.str, name.length);
337
str->append(STRING_WITH_LEN(":="));
338
args[0]->print(str, query_type);
342
bool Item_func_set_user_var::send(Protocol *protocol, String *str_arg)
348
return protocol->store(result_field);
350
return Item::send(protocol, str_arg);
353
void Item_func_set_user_var::make_field(Send_field *tmp_field)
357
result_field->make_field(tmp_field);
358
assert(tmp_field->table_name != 0);
360
tmp_field->col_name=Item::name; // Use user supplied name
363
Item::make_field(tmp_field);
367
Save the value of a user variable into a field
371
field target field to save the value to
372
no_conversion flag indicating whether conversions are allowed
375
Save the function value into a field and update the user variable
376
accordingly. If a result field is defined and the target field doesn't
377
coincide with it then the value from the result field will be used as
378
the new value of the user variable.
380
The reason to have this method rather than simply using the result
381
field in the val_xxx() methods is that the value from the result field
382
not always can be used when the result field is defined.
383
Let's consider the following cases:
384
1) when filling a tmp table the result field is defined but the value of it
385
is undefined because it has to be produced yet. Thus we can't use it.
386
2) on execution of an INSERT ... SELECT statement the save_in_field()
387
function will be called to fill the data in the new record. If the SELECT
388
part uses a tmp table then the result field is defined and should be
389
used in order to get the correct result.
391
The difference between the SET_USER_VAR function and regular functions
392
like CONCAT is that the Item_func objects for the regular functions are
393
replaced by Item_field objects after the values of these functions have
394
been stored in a tmp table. Yet an object of the Item_field class cannot
395
be used to update a user variable.
396
Due to this we have to handle the result field in a special way here and
397
in the Item_func_set_user_var::send() function.
404
int Item_func_set_user_var::save_in_field(Field *field, bool no_conversions,
405
bool can_use_result_field)
407
bool use_result_field= (!can_use_result_field ? 0 :
408
(result_field && result_field != field));
411
/* Update the value of the user variable */
412
check(use_result_field);
415
if (result_type() == STRING_RESULT ||
416
(result_type() == REAL_RESULT && field->result_type() == STRING_RESULT))
419
const CHARSET_INFO * const cs= collation.collation;
420
char buff[MAX_FIELD_WIDTH]; // Alloc buffer for small columns
421
str_value.set_quick(buff, sizeof(buff), cs);
422
result= entry->val_str(&null_value, &str_value, decimals);
426
str_value.set_quick(0, 0, cs);
427
return set_field_to_null_with_conversions(field, no_conversions);
430
/* NOTE: If null_value == false, "result" must be not NULL. */
432
field->set_notnull();
433
error=field->store(result->ptr(),result->length(),cs);
434
str_value.set_quick(0, 0, cs);
436
else if (result_type() == REAL_RESULT)
438
double nr= entry->val_real(&null_value);
440
return set_field_to_null(field);
441
field->set_notnull();
442
error=field->store(nr);
444
else if (result_type() == DECIMAL_RESULT)
446
my_decimal decimal_value;
447
my_decimal *val= entry->val_decimal(&null_value, &decimal_value);
449
return set_field_to_null(field);
450
field->set_notnull();
451
error=field->store_decimal(val);
455
int64_t nr= entry->val_int(&null_value);
457
return set_field_to_null_with_conversions(field, no_conversions);
458
field->set_notnull();
459
error=field->store(nr, unsigned_flag);