1
1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
2
* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
4
* Copyright (C) 2008 Sun Microsystems
4
* Copyright (C) 2008 Sun Microsystems, Inc.
6
6
* This program is free software; you can redistribute it and/or modify
7
7
* it under the terms of the GNU General Public License as published by
17
17
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20
#include <drizzled/server_includes.h>
22
22
#include <drizzled/function/set_user_var.h>
23
#include <drizzled/function/get_variable.h>
24
#include <drizzled/function/update_hash.h>
25
23
#include <drizzled/field/num.h>
26
#include <drizzled/virtual_column_info.h>
27
24
#include <drizzled/session.h>
25
#include <drizzled/plugin/client.h>
26
#include <drizzled/user_var_entry.h>
27
#include <drizzled/table.h>
30
32
When a user variable is updated (in a SET command or a query like
36
38
assert(fixed == 0);
37
39
/* fix_fields will call Item_func_set_user_var::fix_length_and_dec */
38
40
if (Item_func::fix_fields(session, ref) ||
39
!(entry= get_variable(&session->user_vars, name, 1)))
41
!(entry= session->getVariable(name, true)))
42
44
Remember the last query which updated it, this way a query can later know
43
45
if this variable is a constant item in the query (it is if update_query_id
44
46
is different from query_id).
46
entry->update_query_id= session->query_id;
48
entry->update_query_id= session->getQueryId();
48
50
As it is wrong and confusing to associate any
49
51
character set with NULL, @a should be latin2
91
93
Table *table= (Table *) arg;
92
if (result_field->table == table || !table)
93
bitmap_set_bit(result_field->table->read_set, result_field->field_index);
94
if (result_field->vcol_info && result_field->vcol_info->expr_item)
95
return result_field->vcol_info->
96
expr_item->walk(&Item::register_field_in_read_map, 1, arg);
102
Mark field in bitmap supplied as *arg
106
bool Item_func_set_user_var::register_field_in_bitmap(unsigned char *arg)
108
MY_BITMAP *bitmap = (MY_BITMAP *) arg;
112
bitmap_set_bit(bitmap, result_field->field_index);
118
Item_func_set_user_var::update_hash(void *ptr, uint32_t length,
94
if (result_field->getTable() == table || !table)
95
result_field->getTable()->setReadSet(result_field->position());
102
Item_func_set_user_var::update_hash(data_ref data,
119
103
Item_result res_type,
120
const CHARSET_INFO * const cs, Derivation dv,
104
const charset_info_st * const cs, Derivation dv,
121
105
bool unsigned_arg)
127
111
if ((null_value= args[0]->null_value) && null_item)
128
112
res_type= entry->type; // Don't change type of item
129
if (::update_hash(entry, (null_value= args[0]->null_value),
130
ptr, length, res_type, cs, dv, unsigned_arg))
113
entry->update_hash((null_value= args[0]->null_value), data, res_type, cs, dv, unsigned_arg);
158
136
switch (cached_result_type) {
159
137
case REAL_RESULT:
161
save_result.vreal= use_result_field ? result_field->val_real() :
139
save_result.vreal= use_result_field ? result_field->val_real() :
167
save_result.vint= use_result_field ? result_field->val_int() :
169
unsigned_flag= use_result_field ? ((Field_num*)result_field)->unsigned_flag:
170
args[0]->unsigned_flag;
145
save_result.vint= use_result_field ? result_field->val_int() :
148
unsigned_flag= use_result_field ? ((Field_num*)result_field)->unsigned_flag:
149
args[0]->unsigned_flag;
173
153
case STRING_RESULT:
175
save_result.vstr= use_result_field ? result_field->val_str(&value) :
176
args[0]->val_str(&value);
155
save_result.vstr= use_result_field ? result_field->val_str_internal(&value) :
156
args[0]->val_str(&value);
179
159
case DECIMAL_RESULT:
181
save_result.vdec= use_result_field ?
182
result_field->val_decimal(&decimal_buff) :
183
args[0]->val_decimal(&decimal_buff);
161
save_result.vdec= use_result_field ?
162
result_field->val_decimal(&decimal_buff) :
163
args[0]->val_decimal(&decimal_buff);
188
167
// This case should never be chosen
211
191
Item_func_set_user_var::update()
215
193
switch (cached_result_type) {
216
194
case REAL_RESULT:
218
res= update_hash((void*) &save_result.vreal,sizeof(save_result.vreal),
219
REAL_RESULT, &my_charset_bin, DERIVATION_IMPLICIT, 0);
196
update_hash(data_ref(&save_result.vreal, sizeof(save_result.vreal)), REAL_RESULT, &my_charset_bin, DERIVATION_IMPLICIT, 0);
224
res= update_hash((void*) &save_result.vint, sizeof(save_result.vint),
225
INT_RESULT, &my_charset_bin, DERIVATION_IMPLICIT,
202
update_hash(data_ref(&save_result.vint, sizeof(save_result.vint)), INT_RESULT, &my_charset_bin, DERIVATION_IMPLICIT, unsigned_flag);
229
206
case STRING_RESULT:
231
if (!save_result.vstr) // Null value
232
res= update_hash((void*) 0, 0, STRING_RESULT, &my_charset_bin,
233
DERIVATION_IMPLICIT, 0);
235
res= update_hash((void*) save_result.vstr->ptr(),
236
save_result.vstr->length(), STRING_RESULT,
237
save_result.vstr->charset(),
238
DERIVATION_IMPLICIT, 0);
208
if (!save_result.vstr) // Null value
209
update_hash(data_ref(), STRING_RESULT, &my_charset_bin, DERIVATION_IMPLICIT, 0);
211
update_hash(*save_result.vstr, STRING_RESULT, save_result.vstr->charset(), DERIVATION_IMPLICIT, 0);
241
215
case DECIMAL_RESULT:
243
if (!save_result.vdec) // Null value
244
res= update_hash((void*) 0, 0, DECIMAL_RESULT, &my_charset_bin,
245
DERIVATION_IMPLICIT, 0);
247
res= update_hash((void*) save_result.vdec,
248
sizeof(my_decimal), DECIMAL_RESULT,
249
&my_charset_bin, DERIVATION_IMPLICIT, 0);
217
if (!save_result.vdec) // Null value
218
update_hash(data_ref(), DECIMAL_RESULT, &my_charset_bin, DERIVATION_IMPLICIT, 0);
220
update_hash(data_ref(save_result.vdec, sizeof(type::Decimal)), DECIMAL_RESULT, &my_charset_bin, DERIVATION_IMPLICIT, 0);
254
225
// This case should never be chosen
261
231
double Item_func_set_user_var::val_real()
324
294
return entry->val_decimal(&null_value, val);
327
void Item_func_set_user_var::print(String *str, enum_query_type query_type)
297
void Item_func_set_user_var::print(String *str)
329
299
str->append(STRING_WITH_LEN("(@"));
330
str->append(name.str, name.length);
331
str->append(STRING_WITH_LEN(":="));
332
args[0]->print(str, query_type);
337
void Item_func_set_user_var::print_as_stmt(String *str,
338
enum_query_type query_type)
340
str->append(STRING_WITH_LEN("set @"));
341
str->append(name.str, name.length);
342
str->append(STRING_WITH_LEN(":="));
343
args[0]->print(str, query_type);
347
bool Item_func_set_user_var::send(Protocol *protocol, String *str_arg)
301
str->append(STRING_WITH_LEN(":="));
306
void Item_func_set_user_var::send(plugin::Client *client, String *str_arg)
349
308
if (result_field)
353
return protocol->store(result_field);
312
client->store(result_field);
355
return Item::send(protocol, str_arg);
315
Item::send(client, str_arg);
358
void Item_func_set_user_var::make_field(Send_field *tmp_field)
318
void Item_func_set_user_var::make_field(SendField *tmp_field)
360
320
if (result_field)
421
383
(result_type() == REAL_RESULT && field->result_type() == STRING_RESULT))
424
const CHARSET_INFO * const cs= collation.collation;
386
const charset_info_st * const cs= collation.collation;
425
387
char buff[MAX_FIELD_WIDTH]; // Alloc buffer for small columns
426
388
str_value.set_quick(buff, sizeof(buff), cs);
427
389
result= entry->val_str(&null_value, &str_value, decimals);
449
411
else if (result_type() == DECIMAL_RESULT)
451
my_decimal decimal_value;
452
my_decimal *val= entry->val_decimal(&null_value, &decimal_value);
413
type::Decimal decimal_value;
414
type::Decimal *val= entry->val_decimal(&null_value, &decimal_value);
454
416
return set_field_to_null(field);
455
417
field->set_notnull();