1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
|
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
*
* Copyright (C) 2008 Sun Microsystems
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <drizzled/server_includes.h>
#include CSTDINT_H
#include <drizzled/function/update_hash.h>
#include <drizzled/session.h>
/**
Set value to user variable.
@param entry pointer to structure representing variable
@param set_null should we set NULL value ?
@param ptr pointer to buffer with new value
@param length length of new value
@param type type of new value
@param cs charset info for new value
@param dv derivation for new value
@param unsigned_arg indiates if a value of type INT_RESULT is unsigned
@note Sets error and fatal error if allocation fails.
@retval
false success
@retval
true failure
*/
#define extra_size sizeof(double)
bool
update_hash(user_var_entry *entry, bool set_null, void *ptr, uint32_t length,
Item_result type, const CHARSET_INFO * const cs, Derivation dv,
bool unsigned_arg)
{
if (set_null)
{
char *pos= (char*) entry+ ALIGN_SIZE(sizeof(user_var_entry));
if (entry->value && entry->value != pos)
free(entry->value);
entry->value= 0;
entry->length= 0;
}
else
{
if (type == STRING_RESULT)
length++; // Store strings with end \0
if (length <= extra_size)
{
/* Save value in value struct */
char *pos= (char*) entry+ ALIGN_SIZE(sizeof(user_var_entry));
if (entry->value != pos)
{
if (entry->value)
free(entry->value);
entry->value=pos;
}
}
else
{
/* Allocate variable */
if (entry->length != length)
{
char *pos= (char*) entry+ ALIGN_SIZE(sizeof(user_var_entry));
if (entry->value == pos)
entry->value=0;
void *tmpptr= realloc(entry->value, length);
if (tmpptr == NULL)
return 1;
entry->value= (char *)tmpptr;
}
}
if (type == STRING_RESULT)
{
length--; // Fix length change above
entry->value[length]= 0; // Store end \0
}
memcpy(entry->value,ptr,length);
if (type == DECIMAL_RESULT)
((my_decimal*)entry->value)->fix_buffer_pointer();
entry->length= length;
entry->collation.set(cs, dv);
entry->unsigned_flag= unsigned_arg;
}
entry->type=type;
return 0;
}
|