~drizzle-trunk/drizzle/development

641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
1
/*****************************************************************************
2
3
Copyright (c) 1997, 2009, Innobase Oy. All Rights Reserved.
4
5
This program is free software; you can redistribute it and/or modify it under
6
the terms of the GNU General Public License as published by the Free Software
7
Foundation; version 2 of the License.
8
9
This program is distributed in the hope that it will be useful, but WITHOUT
10
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12
13
You should have received a copy of the GNU General Public License along with
1802.10.2 by Monty Taylor
Update all of the copyright headers to include the correct address.
14
this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
15
St, Fifth Floor, Boston, MA 02110-1301 USA
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
16
17
*****************************************************************************/
18
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
19
/**************************************************//**
20
@file eval/eval0eval.c
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
21
SQL evaluator: evaluates simple data structures, like expressions, in
22
a query graph
23
24
Created 12/29/1997 Heikki Tuuri
25
*******************************************************/
26
27
#include "eval0eval.h"
28
29
#ifdef UNIV_NONINL
30
#include "eval0eval.ic"
31
#endif
32
33
#include "data0data.h"
34
#include "row0sel.h"
35
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
36
/** The RND function seed */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
37
static ulint	eval_rnd	= 128367121;
38
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
39
/** Dummy adress used when we should allocate a buffer of size 0 in
40
eval_node_alloc_val_buf */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
41
42
static byte	eval_dummy;
43
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
44
/*****************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
45
Allocate a buffer from global dynamic memory for a value of a que_node.
46
NOTE that this memory must be explicitly freed when the query graph is
47
freed. If the node already has an allocated buffer, that buffer is freed
48
here. NOTE that this is the only function where dynamic memory should be
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
49
allocated for a query node val field.
50
@return	pointer to allocated buffer */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
51
UNIV_INTERN
52
byte*
53
eval_node_alloc_val_buf(
54
/*====================*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
55
	que_node_t*	node,	/*!< in: query graph node; sets the val field
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
56
				data field to point to the new buffer, and
57
				len field equal to size */
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
58
	ulint		size)	/*!< in: buffer size */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
59
{
60
	dfield_t*	dfield;
61
	byte*		data;
62
63
	ut_ad(que_node_get_type(node) == QUE_NODE_SYMBOL
64
	      || que_node_get_type(node) == QUE_NODE_FUNC);
65
66
	dfield = que_node_get_val(node);
67
68
	data = dfield_get_data(dfield);
69
70
	if (data && data != &eval_dummy) {
71
		mem_free(data);
72
	}
73
74
	if (size == 0) {
75
		data = &eval_dummy;
76
	} else {
77
		data = mem_alloc(size);
78
	}
79
80
	que_node_set_val_buf_size(node, size);
81
82
	dfield_set_data(dfield, data, size);
83
84
	return(data);
85
}
86
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
87
/*****************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
88
Free the buffer from global dynamic memory for a value of a que_node,
89
if it has been allocated in the above function. The freeing for pushed
90
column values is done in sel_col_prefetch_buf_free. */
91
UNIV_INTERN
92
void
93
eval_node_free_val_buf(
94
/*===================*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
95
	que_node_t*	node)	/*!< in: query graph node */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
96
{
97
	dfield_t*	dfield;
98
	byte*		data;
99
100
	ut_ad(que_node_get_type(node) == QUE_NODE_SYMBOL
101
	      || que_node_get_type(node) == QUE_NODE_FUNC);
102
103
	dfield = que_node_get_val(node);
104
105
	data = dfield_get_data(dfield);
106
107
	if (que_node_get_val_buf_size(node) > 0) {
108
		ut_a(data);
109
110
		mem_free(data);
111
	}
112
}
113
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
114
/*****************************************************************//**
115
Evaluates a comparison node.
116
@return	the result of the comparison */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
117
UNIV_INTERN
118
ibool
119
eval_cmp(
120
/*=====*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
121
	func_node_t*	cmp_node)	/*!< in: comparison node */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
122
{
123
	que_node_t*	arg1;
124
	que_node_t*	arg2;
125
	int		res;
126
	ibool		val;
127
	int		func;
128
129
	ut_ad(que_node_get_type(cmp_node) == QUE_NODE_FUNC);
130
131
	arg1 = cmp_node->args;
132
	arg2 = que_node_get_next(arg1);
133
134
	res = cmp_dfield_dfield(que_node_get_val(arg1),
135
				que_node_get_val(arg2));
136
	val = TRUE;
137
138
	func = cmp_node->func;
139
140
	if (func == '=') {
141
		if (res != 0) {
142
			val = FALSE;
143
		}
144
	} else if (func == '<') {
145
		if (res != -1) {
146
			val = FALSE;
147
		}
148
	} else if (func == PARS_LE_TOKEN) {
149
		if (res == 1) {
150
			val = FALSE;
151
		}
152
	} else if (func == PARS_NE_TOKEN) {
153
		if (res == 0) {
154
			val = FALSE;
155
		}
156
	} else if (func == PARS_GE_TOKEN) {
157
		if (res == -1) {
158
			val = FALSE;
159
		}
160
	} else {
161
		ut_ad(func == '>');
162
163
		if (res != 1) {
164
			val = FALSE;
165
		}
166
	}
167
168
	eval_node_set_ibool_val(cmp_node, val);
169
170
	return(val);
171
}
172
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
173
/*****************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
174
Evaluates a logical operation node. */
175
UNIV_INLINE
176
void
177
eval_logical(
178
/*=========*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
179
	func_node_t*	logical_node)	/*!< in: logical operation node */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
180
{
181
	que_node_t*	arg1;
182
	que_node_t*	arg2;
183
	ibool		val1;
184
	ibool		val2 = 0; /* remove warning */
185
	ibool		val = 0;  /* remove warning */
186
	int		func;
187
188
	ut_ad(que_node_get_type(logical_node) == QUE_NODE_FUNC);
189
190
	arg1 = logical_node->args;
191
	arg2 = que_node_get_next(arg1); /* arg2 is NULL if func is 'NOT' */
192
193
	val1 = eval_node_get_ibool_val(arg1);
194
195
	if (arg2) {
196
		val2 = eval_node_get_ibool_val(arg2);
197
	}
198
199
	func = logical_node->func;
200
201
	if (func == PARS_AND_TOKEN) {
202
		val = val1 & val2;
203
	} else if (func == PARS_OR_TOKEN) {
204
		val = val1 | val2;
205
	} else if (func == PARS_NOT_TOKEN) {
206
		val = TRUE - val1;
207
	} else {
208
		ut_error;
209
	}
210
211
	eval_node_set_ibool_val(logical_node, val);
212
}
213
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
214
/*****************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
215
Evaluates an arithmetic operation node. */
216
UNIV_INLINE
217
void
218
eval_arith(
219
/*=======*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
220
	func_node_t*	arith_node)	/*!< in: arithmetic operation node */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
221
{
222
	que_node_t*	arg1;
223
	que_node_t*	arg2;
224
	lint		val1;
225
	lint		val2 = 0; /* remove warning */
226
	lint		val;
227
	int		func;
228
229
	ut_ad(que_node_get_type(arith_node) == QUE_NODE_FUNC);
230
231
	arg1 = arith_node->args;
232
	arg2 = que_node_get_next(arg1); /* arg2 is NULL if func is unary '-' */
233
234
	val1 = eval_node_get_int_val(arg1);
235
236
	if (arg2) {
237
		val2 = eval_node_get_int_val(arg2);
238
	}
239
240
	func = arith_node->func;
241
242
	if (func == '+') {
243
		val = val1 + val2;
244
	} else if ((func == '-') && arg2) {
245
		val = val1 - val2;
246
	} else if (func == '-') {
247
		val = -val1;
248
	} else if (func == '*') {
249
		val = val1 * val2;
250
	} else {
251
		ut_ad(func == '/');
252
		val = val1 / val2;
253
	}
254
255
	eval_node_set_int_val(arith_node, val);
256
}
257
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
258
/*****************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
259
Evaluates an aggregate operation node. */
260
UNIV_INLINE
261
void
262
eval_aggregate(
263
/*===========*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
264
	func_node_t*	node)	/*!< in: aggregate operation node */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
265
{
266
	que_node_t*	arg;
267
	lint		val;
268
	lint		arg_val;
269
	int		func;
270
271
	ut_ad(que_node_get_type(node) == QUE_NODE_FUNC);
272
273
	val = eval_node_get_int_val(node);
274
275
	func = node->func;
276
277
	if (func == PARS_COUNT_TOKEN) {
278
279
		val = val + 1;
280
	} else {
281
		ut_ad(func == PARS_SUM_TOKEN);
282
283
		arg = node->args;
284
		arg_val = eval_node_get_int_val(arg);
285
286
		val = val + arg_val;
287
	}
288
289
	eval_node_set_int_val(node, val);
290
}
291
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
292
/*****************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
293
Evaluates a predefined function node where the function is not relevant
294
in benchmarks. */
295
static
296
void
297
eval_predefined_2(
298
/*==============*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
299
	func_node_t*	func_node)	/*!< in: predefined function node */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
300
{
301
	que_node_t*	arg;
302
	que_node_t*	arg1;
303
	que_node_t*	arg2 = 0; /* remove warning (??? bug ???) */
304
	lint		int_val;
305
	byte*		data;
306
	ulint		len1;
307
	ulint		len2;
308
	int		func;
309
	ulint		i;
310
311
	ut_ad(que_node_get_type(func_node) == QUE_NODE_FUNC);
312
313
	arg1 = func_node->args;
314
315
	if (arg1) {
316
		arg2 = que_node_get_next(arg1);
317
	}
318
319
	func = func_node->func;
320
321
	if (func == PARS_PRINTF_TOKEN) {
322
323
		arg = arg1;
324
325
		while (arg) {
326
			dfield_print(que_node_get_val(arg));
327
328
			arg = que_node_get_next(arg);
329
		}
330
331
		putc('\n', stderr);
332
333
	} else if (func == PARS_ASSERT_TOKEN) {
334
335
		if (!eval_node_get_ibool_val(arg1)) {
336
			fputs("SQL assertion fails in a stored procedure!\n",
337
			      stderr);
338
		}
339
340
		ut_a(eval_node_get_ibool_val(arg1));
341
342
		/* This function, or more precisely, a debug procedure,
343
		returns no value */
344
345
	} else if (func == PARS_RND_TOKEN) {
346
347
		len1 = (ulint)eval_node_get_int_val(arg1);
348
		len2 = (ulint)eval_node_get_int_val(arg2);
349
350
		ut_ad(len2 >= len1);
351
352
		if (len2 > len1) {
353
			int_val = (lint) (len1
354
					  + (eval_rnd % (len2 - len1 + 1)));
355
		} else {
356
			int_val = (lint) len1;
357
		}
358
359
		eval_rnd = ut_rnd_gen_next_ulint(eval_rnd);
360
361
		eval_node_set_int_val(func_node, int_val);
362
363
	} else if (func == PARS_RND_STR_TOKEN) {
364
365
		len1 = (ulint)eval_node_get_int_val(arg1);
366
367
		data = eval_node_ensure_val_buf(func_node, len1);
368
369
		for (i = 0; i < len1; i++) {
370
			data[i] = (byte)(97 + (eval_rnd % 3));
371
372
			eval_rnd = ut_rnd_gen_next_ulint(eval_rnd);
373
		}
374
	} else {
375
		ut_error;
376
	}
377
}
378
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
379
/*****************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
380
Evaluates a notfound-function node. */
381
UNIV_INLINE
382
void
383
eval_notfound(
384
/*==========*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
385
	func_node_t*	func_node)	/*!< in: function node */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
386
{
387
	sym_node_t*	cursor;
388
	sel_node_t*	sel_node;
389
	ibool		ibool_val;
390
391
	ut_ad(func_node->func == PARS_NOTFOUND_TOKEN);
392
1819.9.99 by Vasil Dimov
Merge Revision revid:vasil.dimov@oracle.com-20100914091100-rujjqlwtu4oykis3 from MySQL InnoDB
393
	cursor = func_node->args;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
394
395
	ut_ad(que_node_get_type(cursor) == QUE_NODE_SYMBOL);
396
397
	if (cursor->token_type == SYM_LIT) {
398
399
		ut_ad(ut_memcmp(dfield_get_data(que_node_get_val(cursor)),
400
				"SQL", 3) == 0);
401
402
		sel_node = cursor->sym_table->query_graph->last_sel_node;
403
	} else {
404
		sel_node = cursor->alias->cursor_def;
405
	}
406
407
	if (sel_node->state == SEL_NODE_NO_MORE_ROWS) {
408
		ibool_val = TRUE;
409
	} else {
410
		ibool_val = FALSE;
411
	}
412
413
	eval_node_set_ibool_val(func_node, ibool_val);
414
}
415
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
416
/*****************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
417
Evaluates a substr-function node. */
418
UNIV_INLINE
419
void
420
eval_substr(
421
/*========*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
422
	func_node_t*	func_node)	/*!< in: function node */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
423
{
424
	que_node_t*	arg1;
425
	que_node_t*	arg2;
426
	que_node_t*	arg3;
427
	dfield_t*	dfield;
428
	byte*		str1;
429
	ulint		len1;
430
	ulint		len2;
431
432
	arg1 = func_node->args;
433
	arg2 = que_node_get_next(arg1);
434
435
	ut_ad(func_node->func == PARS_SUBSTR_TOKEN);
436
437
	arg3 = que_node_get_next(arg2);
438
439
	str1 = dfield_get_data(que_node_get_val(arg1));
440
441
	len1 = (ulint)eval_node_get_int_val(arg2);
442
	len2 = (ulint)eval_node_get_int_val(arg3);
443
444
	dfield = que_node_get_val(func_node);
445
446
	dfield_set_data(dfield, str1 + len1, len2);
447
}
448
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
449
/*****************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
450
Evaluates a replstr-procedure node. */
451
static
452
void
453
eval_replstr(
454
/*=========*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
455
	func_node_t*	func_node)	/*!< in: function node */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
456
{
457
	que_node_t*	arg1;
458
	que_node_t*	arg2;
459
	que_node_t*	arg3;
460
	que_node_t*	arg4;
461
	byte*		str1;
462
	byte*		str2;
463
	ulint		len1;
464
	ulint		len2;
465
466
	arg1 = func_node->args;
467
	arg2 = que_node_get_next(arg1);
468
469
	ut_ad(que_node_get_type(arg1) == QUE_NODE_SYMBOL);
470
471
	arg3 = que_node_get_next(arg2);
472
	arg4 = que_node_get_next(arg3);
473
474
	str1 = dfield_get_data(que_node_get_val(arg1));
475
	str2 = dfield_get_data(que_node_get_val(arg2));
476
477
	len1 = (ulint)eval_node_get_int_val(arg3);
478
	len2 = (ulint)eval_node_get_int_val(arg4);
479
480
	if ((dfield_get_len(que_node_get_val(arg1)) < len1 + len2)
481
	    || (dfield_get_len(que_node_get_val(arg2)) < len2)) {
482
483
		ut_error;
484
	}
485
486
	ut_memcpy(str1 + len1, str2, len2);
487
}
488
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
489
/*****************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
490
Evaluates an instr-function node. */
491
static
492
void
493
eval_instr(
494
/*=======*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
495
	func_node_t*	func_node)	/*!< in: function node */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
496
{
497
	que_node_t*	arg1;
498
	que_node_t*	arg2;
499
	dfield_t*	dfield1;
500
	dfield_t*	dfield2;
501
	lint		int_val;
502
	byte*		str1;
503
	byte*		str2;
504
	byte		match_char;
505
	ulint		len1;
506
	ulint		len2;
507
	ulint		i;
508
	ulint		j;
509
510
	arg1 = func_node->args;
511
	arg2 = que_node_get_next(arg1);
512
513
	dfield1 = que_node_get_val(arg1);
514
	dfield2 = que_node_get_val(arg2);
515
516
	str1 = dfield_get_data(dfield1);
517
	str2 = dfield_get_data(dfield2);
518
519
	len1 = dfield_get_len(dfield1);
520
	len2 = dfield_get_len(dfield2);
521
522
	if (len2 == 0) {
523
		ut_error;
524
	}
525
526
	match_char = str2[0];
527
528
	for (i = 0; i < len1; i++) {
529
		/* In this outer loop, the number of matched characters is 0 */
530
531
		if (str1[i] == match_char) {
532
533
			if (i + len2 > len1) {
534
535
				break;
536
			}
537
538
			for (j = 1;; j++) {
539
				/* We have already matched j characters */
540
541
				if (j == len2) {
542
					int_val = i + 1;
543
544
					goto match_found;
545
				}
546
547
				if (str1[i + j] != str2[j]) {
548
549
					break;
550
				}
551
			}
552
		}
553
	}
554
555
	int_val = 0;
556
557
match_found:
558
	eval_node_set_int_val(func_node, int_val);
559
}
560
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
561
/*****************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
562
Evaluates a predefined function node. */
563
UNIV_INLINE
564
void
565
eval_binary_to_number(
566
/*==================*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
567
	func_node_t*	func_node)	/*!< in: function node */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
568
{
569
	que_node_t*	arg1;
570
	dfield_t*	dfield;
571
	byte*		str1;
572
	byte*		str2;
573
	ulint		len1;
574
	ulint		int_val;
575
576
	arg1 = func_node->args;
577
578
	dfield = que_node_get_val(arg1);
579
580
	str1 = dfield_get_data(dfield);
581
	len1 = dfield_get_len(dfield);
582
583
	if (len1 > 4) {
584
		ut_error;
585
	}
586
587
	if (len1 == 4) {
588
		str2 = str1;
589
	} else {
590
		int_val = 0;
591
		str2 = (byte*)&int_val;
592
593
		ut_memcpy(str2 + (4 - len1), str1, len1);
594
	}
595
596
	eval_node_copy_and_alloc_val(func_node, str2, 4);
597
}
598
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
599
/*****************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
600
Evaluates a predefined function node. */
601
static
602
void
603
eval_concat(
604
/*========*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
605
	func_node_t*	func_node)	/*!< in: function node */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
606
{
607
	que_node_t*	arg;
608
	dfield_t*	dfield;
609
	byte*		data;
610
	ulint		len;
611
	ulint		len1;
612
613
	arg = func_node->args;
614
	len = 0;
615
616
	while (arg) {
617
		len1 = dfield_get_len(que_node_get_val(arg));
618
619
		len += len1;
620
621
		arg = que_node_get_next(arg);
622
	}
623
624
	data = eval_node_ensure_val_buf(func_node, len);
625
626
	arg = func_node->args;
627
	len = 0;
628
629
	while (arg) {
630
		dfield = que_node_get_val(arg);
631
		len1 = dfield_get_len(dfield);
632
633
		ut_memcpy(data + len, dfield_get_data(dfield), len1);
634
635
		len += len1;
636
637
		arg = que_node_get_next(arg);
638
	}
639
}
640
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
641
/*****************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
642
Evaluates a predefined function node. If the first argument is an integer,
643
this function looks at the second argument which is the integer length in
644
bytes, and converts the integer to a VARCHAR.
645
If the first argument is of some other type, this function converts it to
646
BINARY. */
647
UNIV_INLINE
648
void
649
eval_to_binary(
650
/*===========*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
651
	func_node_t*	func_node)	/*!< in: function node */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
652
{
653
	que_node_t*	arg1;
654
	que_node_t*	arg2;
655
	dfield_t*	dfield;
656
	byte*		str1;
657
	ulint		len;
658
	ulint		len1;
659
660
	arg1 = func_node->args;
661
662
	str1 = dfield_get_data(que_node_get_val(arg1));
663
664
	if (dtype_get_mtype(que_node_get_data_type(arg1)) != DATA_INT) {
665
666
		len = dfield_get_len(que_node_get_val(arg1));
667
668
		dfield = que_node_get_val(func_node);
669
670
		dfield_set_data(dfield, str1, len);
671
672
		return;
673
	}
674
675
	arg2 = que_node_get_next(arg1);
676
677
	len1 = (ulint)eval_node_get_int_val(arg2);
678
679
	if (len1 > 4) {
680
681
		ut_error;
682
	}
683
684
	dfield = que_node_get_val(func_node);
685
686
	dfield_set_data(dfield, str1 + (4 - len1), len1);
687
}
688
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
689
/*****************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
690
Evaluates a predefined function node. */
691
UNIV_INLINE
692
void
693
eval_predefined(
694
/*============*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
695
	func_node_t*	func_node)	/*!< in: function node */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
696
{
697
	que_node_t*	arg1;
698
	lint		int_val;
699
	byte*		data;
700
	int		func;
701
702
	func = func_node->func;
703
704
	arg1 = func_node->args;
705
706
	if (func == PARS_LENGTH_TOKEN) {
707
708
		int_val = (lint)dfield_get_len(que_node_get_val(arg1));
709
710
	} else if (func == PARS_TO_CHAR_TOKEN) {
711
712
		/* Convert number to character string as a
713
		signed decimal integer. */
714
715
		ulint	uint_val;
716
		int	int_len;
717
718
		int_val = eval_node_get_int_val(arg1);
719
720
		/* Determine the length of the string. */
721
722
		if (int_val == 0) {
723
			int_len = 1; /* the number 0 occupies 1 byte */
724
		} else {
725
			int_len = 0;
726
			if (int_val < 0) {
727
				uint_val = ((ulint) -int_val - 1) + 1;
728
				int_len++; /* reserve space for minus sign */
729
			} else {
730
				uint_val = (ulint) int_val;
731
			}
732
			for (; uint_val > 0; int_len++) {
733
				uint_val /= 10;
734
			}
735
		}
736
737
		/* allocate the string */
738
		data = eval_node_ensure_val_buf(func_node, int_len + 1);
739
740
		/* add terminating NUL character */
741
		data[int_len] = 0;
742
743
		/* convert the number */
744
745
		if (int_val == 0) {
746
			data[0] = '0';
747
		} else {
748
			int tmp;
749
			if (int_val < 0) {
750
				data[0] = '-'; /* preceding minus sign */
751
				uint_val = ((ulint) -int_val - 1) + 1;
752
			} else {
753
				uint_val = (ulint) int_val;
754
			}
755
			for (tmp = int_len; uint_val > 0; uint_val /= 10) {
756
				data[--tmp] = (byte)
757
					('0' + (byte)(uint_val % 10));
758
			}
759
		}
760
761
		dfield_set_len(que_node_get_val(func_node), int_len);
762
763
		return;
764
765
	} else if (func == PARS_TO_NUMBER_TOKEN) {
766
767
		int_val = atoi((char*)
768
			       dfield_get_data(que_node_get_val(arg1)));
769
770
	} else if (func == PARS_SYSDATE_TOKEN) {
771
		int_val = (lint)ut_time();
772
	} else {
773
		eval_predefined_2(func_node);
774
775
		return;
776
	}
777
778
	eval_node_set_int_val(func_node, int_val);
779
}
780
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
781
/*****************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
782
Evaluates a function node. */
783
UNIV_INTERN
784
void
785
eval_func(
786
/*======*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
787
	func_node_t*	func_node)	/*!< in: function node */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
788
{
789
	que_node_t*	arg;
790
	ulint		class;
791
	ulint		func;
792
793
	ut_ad(que_node_get_type(func_node) == QUE_NODE_FUNC);
794
795
	class = func_node->class;
796
	func = func_node->func;
797
798
	arg = func_node->args;
799
800
	/* Evaluate first the argument list */
801
	while (arg) {
802
		eval_exp(arg);
803
804
		/* The functions are not defined for SQL null argument
805
		values, except for eval_cmp and notfound */
806
807
		if (dfield_is_null(que_node_get_val(arg))
808
		    && (class != PARS_FUNC_CMP)
809
		    && (func != PARS_NOTFOUND_TOKEN)
810
		    && (func != PARS_PRINTF_TOKEN)) {
811
			ut_error;
812
		}
813
814
		arg = que_node_get_next(arg);
815
	}
816
817
	if (class == PARS_FUNC_CMP) {
818
		eval_cmp(func_node);
819
	} else if (class == PARS_FUNC_ARITH) {
820
		eval_arith(func_node);
821
	} else if (class == PARS_FUNC_AGGREGATE) {
822
		eval_aggregate(func_node);
823
	} else if (class == PARS_FUNC_PREDEFINED) {
824
825
		if (func == PARS_NOTFOUND_TOKEN) {
826
			eval_notfound(func_node);
827
		} else if (func == PARS_SUBSTR_TOKEN) {
828
			eval_substr(func_node);
829
		} else if (func == PARS_REPLSTR_TOKEN) {
830
			eval_replstr(func_node);
831
		} else if (func == PARS_INSTR_TOKEN) {
832
			eval_instr(func_node);
833
		} else if (func == PARS_BINARY_TO_NUMBER_TOKEN) {
834
			eval_binary_to_number(func_node);
835
		} else if (func == PARS_CONCAT_TOKEN) {
836
			eval_concat(func_node);
837
		} else if (func == PARS_TO_BINARY_TOKEN) {
838
			eval_to_binary(func_node);
839
		} else {
840
			eval_predefined(func_node);
841
		}
842
	} else {
843
		ut_ad(class == PARS_FUNC_LOGICAL);
844
845
		eval_logical(func_node);
846
	}
847
}