1
by brian
clean slate |
1 |
/******************************************************
|
2 |
SQL evaluator: evaluates simple data structures, like expressions, in
|
|
3 |
a query graph
|
|
4 |
||
5 |
(c) 1997 Innobase Oy
|
|
6 |
||
7 |
Created 12/29/1997 Heikki Tuuri
|
|
8 |
*******************************************************/
|
|
9 |
||
10 |
#include "que0que.h" |
|
11 |
#include "rem0cmp.h" |
|
12 |
#include "pars0grm.h" |
|
13 |
||
14 |
/*********************************************************************
|
|
15 |
Evaluates a function node. */
|
|
16 |
||
17 |
void
|
|
18 |
eval_func( |
|
19 |
/*======*/
|
|
20 |
func_node_t* func_node); /* in: function node */ |
|
21 |
/*********************************************************************
|
|
22 |
Allocate a buffer from global dynamic memory for a value of a que_node.
|
|
23 |
NOTE that this memory must be explicitly freed when the query graph is
|
|
24 |
freed. If the node already has allocated buffer, that buffer is freed
|
|
25 |
here. NOTE that this is the only function where dynamic memory should be
|
|
26 |
allocated for a query node val field. */
|
|
27 |
||
28 |
byte* |
|
29 |
eval_node_alloc_val_buf( |
|
30 |
/*====================*/
|
|
31 |
/* out: pointer to allocated buffer */
|
|
32 |
que_node_t* node, /* in: query graph node; sets the val field |
|
33 |
data field to point to the new buffer, and
|
|
34 |
len field equal to size */
|
|
35 |
ulint size); /* in: buffer size */ |
|
36 |
||
37 |
||
38 |
/*********************************************************************
|
|
39 |
Allocates a new buffer if needed. */
|
|
40 |
UNIV_INLINE
|
|
41 |
byte* |
|
42 |
eval_node_ensure_val_buf( |
|
43 |
/*=====================*/
|
|
44 |
/* out: pointer to buffer */
|
|
45 |
que_node_t* node, /* in: query graph node; sets the val field |
|
46 |
data field to point to the new buffer, and
|
|
47 |
len field equal to size */
|
|
48 |
ulint size) /* in: buffer size */ |
|
49 |
{
|
|
50 |
dfield_t* dfield; |
|
51 |
byte* data; |
|
52 |
||
53 |
dfield = que_node_get_val(node); |
|
54 |
dfield_set_len(dfield, size); |
|
55 |
||
56 |
data = dfield_get_data(dfield); |
|
57 |
||
58 |
if (!data || que_node_get_val_buf_size(node) < size) { |
|
59 |
||
60 |
data = eval_node_alloc_val_buf(node, size); |
|
61 |
}
|
|
62 |
||
63 |
return(data); |
|
64 |
}
|
|
65 |
||
66 |
/*********************************************************************
|
|
67 |
Evaluates a symbol table symbol. */
|
|
68 |
UNIV_INLINE
|
|
69 |
void
|
|
70 |
eval_sym( |
|
71 |
/*=====*/
|
|
72 |
sym_node_t* sym_node) /* in: symbol table node */ |
|
73 |
{
|
|
74 |
||
75 |
ut_ad(que_node_get_type(sym_node) == QUE_NODE_SYMBOL); |
|
76 |
||
77 |
if (sym_node->indirection) { |
|
78 |
/* The symbol table node is an alias for a variable or a
|
|
79 |
column */
|
|
80 |
||
81 |
dfield_copy_data(que_node_get_val(sym_node), |
|
82 |
que_node_get_val(sym_node->indirection)); |
|
83 |
}
|
|
84 |
}
|
|
85 |
||
86 |
/*********************************************************************
|
|
87 |
Evaluates an expression. */
|
|
88 |
UNIV_INLINE
|
|
89 |
void
|
|
90 |
eval_exp( |
|
91 |
/*=====*/
|
|
92 |
que_node_t* exp_node) /* in: expression */ |
|
93 |
{
|
|
94 |
if (que_node_get_type(exp_node) == QUE_NODE_SYMBOL) { |
|
95 |
||
96 |
eval_sym((sym_node_t*)exp_node); |
|
97 |
||
98 |
return; |
|
99 |
}
|
|
100 |
||
101 |
eval_func(exp_node); |
|
102 |
}
|
|
103 |
||
104 |
/*********************************************************************
|
|
105 |
Sets an integer value as the value of an expression node. */
|
|
106 |
UNIV_INLINE
|
|
107 |
void
|
|
108 |
eval_node_set_int_val( |
|
109 |
/*==================*/
|
|
110 |
que_node_t* node, /* in: expression node */ |
|
111 |
lint val) /* in: value to set */ |
|
112 |
{
|
|
113 |
dfield_t* dfield; |
|
114 |
byte* data; |
|
115 |
||
116 |
dfield = que_node_get_val(node); |
|
117 |
||
118 |
data = dfield_get_data(dfield); |
|
119 |
||
120 |
if (data == NULL) { |
|
121 |
data = eval_node_alloc_val_buf(node, 4); |
|
122 |
}
|
|
123 |
||
124 |
ut_ad(dfield_get_len(dfield) == 4); |
|
125 |
||
126 |
mach_write_to_4(data, (ulint)val); |
|
127 |
}
|
|
128 |
||
129 |
/*********************************************************************
|
|
130 |
Gets an integer non-SQL null value from an expression node. */
|
|
131 |
UNIV_INLINE
|
|
132 |
lint
|
|
133 |
eval_node_get_int_val( |
|
134 |
/*==================*/
|
|
135 |
/* out: integer value */
|
|
136 |
que_node_t* node) /* in: expression node */ |
|
137 |
{
|
|
138 |
dfield_t* dfield; |
|
139 |
||
140 |
dfield = que_node_get_val(node); |
|
141 |
||
142 |
ut_ad(dfield_get_len(dfield) == 4); |
|
143 |
||
144 |
return((int)mach_read_from_4(dfield_get_data(dfield))); |
|
145 |
}
|
|
146 |
||
147 |
/*********************************************************************
|
|
148 |
Gets a iboolean value from a query node. */
|
|
149 |
UNIV_INLINE
|
|
150 |
ibool
|
|
151 |
eval_node_get_ibool_val( |
|
152 |
/*====================*/
|
|
153 |
/* out: iboolean value */
|
|
154 |
que_node_t* node) /* in: query graph node */ |
|
155 |
{
|
|
156 |
dfield_t* dfield; |
|
157 |
byte* data; |
|
158 |
||
159 |
dfield = que_node_get_val(node); |
|
160 |
||
161 |
data = dfield_get_data(dfield); |
|
162 |
||
163 |
ut_ad(data != NULL); |
|
164 |
||
165 |
return(mach_read_from_1(data)); |
|
166 |
}
|
|
167 |
||
168 |
/*********************************************************************
|
|
169 |
Sets a iboolean value as the value of a function node. */
|
|
170 |
UNIV_INLINE
|
|
171 |
void
|
|
172 |
eval_node_set_ibool_val( |
|
173 |
/*====================*/
|
|
174 |
func_node_t* func_node, /* in: function node */ |
|
175 |
ibool val) /* in: value to set */ |
|
176 |
{
|
|
177 |
dfield_t* dfield; |
|
178 |
byte* data; |
|
179 |
||
180 |
dfield = que_node_get_val(func_node); |
|
181 |
||
182 |
data = dfield_get_data(dfield); |
|
183 |
||
184 |
if (data == NULL) { |
|
185 |
/* Allocate 1 byte to hold the value */
|
|
186 |
||
187 |
data = eval_node_alloc_val_buf(func_node, 1); |
|
188 |
}
|
|
189 |
||
190 |
ut_ad(dfield_get_len(dfield) == 1); |
|
191 |
||
192 |
mach_write_to_1(data, val); |
|
193 |
}
|
|
194 |
||
195 |
/*********************************************************************
|
|
196 |
Copies a binary string value as the value of a query graph node. Allocates a
|
|
197 |
new buffer if necessary. */
|
|
198 |
UNIV_INLINE
|
|
199 |
void
|
|
200 |
eval_node_copy_and_alloc_val( |
|
201 |
/*=========================*/
|
|
202 |
que_node_t* node, /* in: query graph node */ |
|
203 |
byte* str, /* in: binary string */ |
|
204 |
ulint len) /* in: string length or UNIV_SQL_NULL */ |
|
205 |
{
|
|
206 |
byte* data; |
|
207 |
||
208 |
if (len == UNIV_SQL_NULL) { |
|
209 |
dfield_set_len(que_node_get_val(node), len); |
|
210 |
||
211 |
return; |
|
212 |
}
|
|
213 |
||
214 |
data = eval_node_ensure_val_buf(node, len); |
|
215 |
||
216 |
ut_memcpy(data, str, len); |
|
217 |
}
|
|
218 |
||
219 |
/*********************************************************************
|
|
220 |
Copies a query node value to another node. */
|
|
221 |
UNIV_INLINE
|
|
222 |
void
|
|
223 |
eval_node_copy_val( |
|
224 |
/*===============*/
|
|
225 |
que_node_t* node1, /* in: node to copy to */ |
|
226 |
que_node_t* node2) /* in: node to copy from */ |
|
227 |
{
|
|
228 |
dfield_t* dfield2; |
|
229 |
||
230 |
dfield2 = que_node_get_val(node2); |
|
231 |
||
232 |
eval_node_copy_and_alloc_val(node1, dfield_get_data(dfield2), |
|
233 |
dfield_get_len(dfield2)); |
|
234 |
}
|