150
150
return copy_or_same(session);
154
When a user variable is updated (in a SET command or a query like
158
bool Item_func_set_user_var::fix_fields(Session *session, Item **ref)
161
/* fix_fields will call Item_func_set_user_var::fix_length_and_dec */
162
if (Item_func::fix_fields(session, ref) ||
163
!(entry= get_variable(&session->user_vars, name, 1)))
166
Remember the last query which updated it, this way a query can later know
167
if this variable is a constant item in the query (it is if update_query_id
168
is different from query_id).
170
entry->update_query_id= session->query_id;
172
As it is wrong and confusing to associate any
173
character set with NULL, @a should be latin2
174
after this query sequence:
176
SET @a=_latin2'string';
179
I.e. the second query should not change the charset
180
to the current default value, but should keep the
181
original value assigned during the first query.
182
In order to do it, we don't copy charset
183
from the argument if the argument is NULL
184
and the variable has previously been initialized.
186
null_item= (args[0]->type() == NULL_ITEM);
187
if (!entry->collation.collation || !null_item)
188
entry->collation.set(args[0]->collation.collation, DERIVATION_IMPLICIT);
189
collation.set(entry->collation.collation, DERIVATION_IMPLICIT);
190
cached_result_type= args[0]->result_type();
196
Item_func_set_user_var::fix_length_and_dec()
198
maybe_null=args[0]->maybe_null;
199
max_length=args[0]->max_length;
200
decimals=args[0]->decimals;
201
collation.set(args[0]->collation.collation, DERIVATION_IMPLICIT);
206
Mark field in read_map
209
This is used by filesort to register used fields in a a temporary
210
column read set or to register used fields in a view
213
bool Item_func_set_user_var::register_field_in_read_map(unsigned char *arg)
217
Table *table= (Table *) arg;
218
if (result_field->table == table || !table)
219
bitmap_set_bit(result_field->table->read_set, result_field->field_index);
220
if (result_field->vcol_info && result_field->vcol_info->expr_item)
221
return result_field->vcol_info->
222
expr_item->walk(&Item::register_field_in_read_map, 1, arg);
229
Mark field in bitmap supplied as *arg
233
bool Item_func_set_user_var::register_field_in_bitmap(unsigned char *arg)
235
MY_BITMAP *bitmap = (MY_BITMAP *) arg;
239
bitmap_set_bit(bitmap, result_field->field_index);
246
Set value to user variable.
248
@param entry pointer to structure representing variable
249
@param set_null should we set NULL value ?
250
@param ptr pointer to buffer with new value
251
@param length length of new value
252
@param type type of new value
253
@param cs charset info for new value
254
@param dv derivation for new value
255
@param unsigned_arg indiates if a value of type INT_RESULT is unsigned
257
@note Sets error and fatal error if allocation fails.
265
#define extra_size sizeof(double)
268
update_hash(user_var_entry *entry, bool set_null, void *ptr, uint32_t length,
269
Item_result type, const CHARSET_INFO * const cs, Derivation dv,
274
char *pos= (char*) entry+ ALIGN_SIZE(sizeof(user_var_entry));
275
if (entry->value && entry->value != pos)
282
if (type == STRING_RESULT)
283
length++; // Store strings with end \0
284
if (length <= extra_size)
286
/* Save value in value struct */
287
char *pos= (char*) entry+ ALIGN_SIZE(sizeof(user_var_entry));
288
if (entry->value != pos)
297
/* Allocate variable */
298
if (entry->length != length)
300
char *pos= (char*) entry+ ALIGN_SIZE(sizeof(user_var_entry));
301
if (entry->value == pos)
303
entry->value= (char*) my_realloc(entry->value, length,
304
MYF(MY_ALLOW_ZERO_PTR | MY_WME |
310
if (type == STRING_RESULT)
312
length--; // Fix length change above
313
entry->value[length]= 0; // Store end \0
315
memcpy(entry->value,ptr,length);
316
if (type == DECIMAL_RESULT)
317
((my_decimal*)entry->value)->fix_buffer_pointer();
318
entry->length= length;
319
entry->collation.set(cs, dv);
320
entry->unsigned_flag= unsigned_arg;
328
Item_func_set_user_var::update_hash(void *ptr, uint32_t length,
329
Item_result res_type,
330
const CHARSET_INFO * const cs, Derivation dv,
334
If we set a variable explicitely to NULL then keep the old
335
result type of the variable
337
if ((null_value= args[0]->null_value) && null_item)
338
res_type= entry->type; // Don't change type of item
339
if (::update_hash(entry, (null_value= args[0]->null_value),
340
ptr, length, res_type, cs, dv, unsigned_arg))
349
154
/** Get the value of a variable as a double. */
467
This functions is invoked on SET \@variable or
468
\@variable:= expression.
470
Evaluate (and check expression), store results.
473
For now it always return OK. All problem with value evaluating
474
will be caught by session->is_error() check in sql_set_variables().
481
Item_func_set_user_var::check(bool use_result_field)
483
if (use_result_field && !result_field)
484
use_result_field= false;
486
switch (cached_result_type) {
489
save_result.vreal= use_result_field ? result_field->val_real() :
495
save_result.vint= use_result_field ? result_field->val_int() :
497
unsigned_flag= use_result_field ? ((Field_num*)result_field)->unsigned_flag:
498
args[0]->unsigned_flag;
503
save_result.vstr= use_result_field ? result_field->val_str(&value) :
504
args[0]->val_str(&value);
509
save_result.vdec= use_result_field ?
510
result_field->val_decimal(&decimal_buff) :
511
args[0]->val_decimal(&decimal_buff);
516
// This case should never be chosen
525
This functions is invoked on
526
SET \@variable or \@variable:= expression.
529
We have to store the expression as such in the variable, independent of
530
the value method used by the user
540
Item_func_set_user_var::update()
544
switch (cached_result_type) {
547
res= update_hash((void*) &save_result.vreal,sizeof(save_result.vreal),
548
REAL_RESULT, &my_charset_bin, DERIVATION_IMPLICIT, 0);
553
res= update_hash((void*) &save_result.vint, sizeof(save_result.vint),
554
INT_RESULT, &my_charset_bin, DERIVATION_IMPLICIT,
560
if (!save_result.vstr) // Null value
561
res= update_hash((void*) 0, 0, STRING_RESULT, &my_charset_bin,
562
DERIVATION_IMPLICIT, 0);
564
res= update_hash((void*) save_result.vstr->ptr(),
565
save_result.vstr->length(), STRING_RESULT,
566
save_result.vstr->charset(),
567
DERIVATION_IMPLICIT, 0);
572
if (!save_result.vdec) // Null value
573
res= update_hash((void*) 0, 0, DECIMAL_RESULT, &my_charset_bin,
574
DERIVATION_IMPLICIT, 0);
576
res= update_hash((void*) save_result.vdec,
577
sizeof(my_decimal), DECIMAL_RESULT,
578
&my_charset_bin, DERIVATION_IMPLICIT, 0);
583
// This case should never be chosen
591
double Item_func_set_user_var::val_real()
595
update(); // Store expression
596
return entry->val_real(&null_value);
599
int64_t Item_func_set_user_var::val_int()
603
update(); // Store expression
604
return entry->val_int(&null_value);
607
String *Item_func_set_user_var::val_str(String *str)
611
update(); // Store expression
612
return entry->val_str(&null_value, str, decimals);
616
my_decimal *Item_func_set_user_var::val_decimal(my_decimal *val)
620
update(); // Store expression
621
return entry->val_decimal(&null_value, val);
625
double Item_func_set_user_var::val_result()
629
update(); // Store expression
630
return entry->val_real(&null_value);
633
int64_t Item_func_set_user_var::val_int_result()
637
update(); // Store expression
638
return entry->val_int(&null_value);
641
String *Item_func_set_user_var::str_result(String *str)
645
update(); // Store expression
646
return entry->val_str(&null_value, str, decimals);
650
my_decimal *Item_func_set_user_var::val_decimal_result(my_decimal *val)
654
update(); // Store expression
655
return entry->val_decimal(&null_value, val);
659
void Item_func_set_user_var::print(String *str, enum_query_type query_type)
661
str->append(STRING_WITH_LEN("(@"));
662
str->append(name.str, name.length);
663
str->append(STRING_WITH_LEN(":="));
664
args[0]->print(str, query_type);
669
void Item_func_set_user_var::print_as_stmt(String *str,
670
enum_query_type query_type)
672
str->append(STRING_WITH_LEN("set @"));
673
str->append(name.str, name.length);
674
str->append(STRING_WITH_LEN(":="));
675
args[0]->print(str, query_type);
679
bool Item_func_set_user_var::send(Protocol *protocol, String *str_arg)
685
return protocol->store(result_field);
687
return Item::send(protocol, str_arg);
690
void Item_func_set_user_var::make_field(Send_field *tmp_field)
694
result_field->make_field(tmp_field);
695
assert(tmp_field->table_name != 0);
697
tmp_field->col_name=Item::name; // Use user supplied name
700
Item::make_field(tmp_field);
705
Save the value of a user variable into a field
709
field target field to save the value to
710
no_conversion flag indicating whether conversions are allowed
713
Save the function value into a field and update the user variable
714
accordingly. If a result field is defined and the target field doesn't
715
coincide with it then the value from the result field will be used as
716
the new value of the user variable.
718
The reason to have this method rather than simply using the result
719
field in the val_xxx() methods is that the value from the result field
720
not always can be used when the result field is defined.
721
Let's consider the following cases:
722
1) when filling a tmp table the result field is defined but the value of it
723
is undefined because it has to be produced yet. Thus we can't use it.
724
2) on execution of an INSERT ... SELECT statement the save_in_field()
725
function will be called to fill the data in the new record. If the SELECT
726
part uses a tmp table then the result field is defined and should be
727
used in order to get the correct result.
729
The difference between the SET_USER_VAR function and regular functions
730
like CONCAT is that the Item_func objects for the regular functions are
731
replaced by Item_field objects after the values of these functions have
732
been stored in a tmp table. Yet an object of the Item_field class cannot
733
be used to update a user variable.
734
Due to this we have to handle the result field in a special way here and
735
in the Item_func_set_user_var::send() function.
742
int Item_func_set_user_var::save_in_field(Field *field, bool no_conversions,
743
bool can_use_result_field)
745
bool use_result_field= (!can_use_result_field ? 0 :
746
(result_field && result_field != field));
749
/* Update the value of the user variable */
750
check(use_result_field);
753
if (result_type() == STRING_RESULT ||
754
(result_type() == REAL_RESULT && field->result_type() == STRING_RESULT))
757
const CHARSET_INFO * const cs= collation.collation;
758
char buff[MAX_FIELD_WIDTH]; // Alloc buffer for small columns
759
str_value.set_quick(buff, sizeof(buff), cs);
760
result= entry->val_str(&null_value, &str_value, decimals);
764
str_value.set_quick(0, 0, cs);
765
return set_field_to_null_with_conversions(field, no_conversions);
768
/* NOTE: If null_value == false, "result" must be not NULL. */
770
field->set_notnull();
771
error=field->store(result->ptr(),result->length(),cs);
772
str_value.set_quick(0, 0, cs);
774
else if (result_type() == REAL_RESULT)
776
double nr= entry->val_real(&null_value);
778
return set_field_to_null(field);
779
field->set_notnull();
780
error=field->store(nr);
782
else if (result_type() == DECIMAL_RESULT)
784
my_decimal decimal_value;
785
my_decimal *val= entry->val_decimal(&null_value, &decimal_value);
787
return set_field_to_null(field);
788
field->set_notnull();
789
error=field->store_decimal(val);
793
int64_t nr= entry->val_int(&null_value);
795
return set_field_to_null_with_conversions(field, no_conversions);
796
field->set_notnull();
797
error=field->store(nr, unsigned_flag);
803
bool Item_user_var_as_out_param::fix_fields(Session *session, Item **ref)
806
if (Item::fix_fields(session, ref) ||
807
!(entry= get_variable(&session->user_vars, name, 1)))
809
entry->type= STRING_RESULT;
811
Let us set the same collation which is used for loading
812
of fields in LOAD DATA INFILE.
813
(Since Item_user_var_as_out_param is used only there).
815
entry->collation.set(session->variables.collation_database);
816
entry->update_query_id= session->query_id;
821
void Item_user_var_as_out_param::set_null_value(const CHARSET_INFO * const cs)
823
::update_hash(entry, true, 0, 0, STRING_RESULT, cs,
824
DERIVATION_IMPLICIT, 0 /* unsigned_arg */);
828
void Item_user_var_as_out_param::set_value(const char *str, uint32_t length,
829
const CHARSET_INFO * const cs)
831
::update_hash(entry, false, (void*)str, length, STRING_RESULT, cs,
832
DERIVATION_IMPLICIT, 0 /* unsigned_arg */);
836
double Item_user_var_as_out_param::val_real()
843
int64_t Item_user_var_as_out_param::val_int()
850
String* Item_user_var_as_out_param::val_str(String *str __attribute__((unused)))
857
my_decimal* Item_user_var_as_out_param::val_decimal(my_decimal *decimal_buffer __attribute__((unused)))
864
void Item_user_var_as_out_param::print(String *str,
865
enum_query_type query_type __attribute__((unused)))
868
str->append(name.str,name.length);
871
/***************************************************************************
873
****************************************************************************/
876
Return value of an system variable base[.name] as a constant item.
878
@param session Thread handler
879
@param var_type global / session
880
@param name Name of base or system variable
881
@param component Component.
884
If component.str = 0 then the variable name is in 'name'