1
/******************************************************
2
SQL evaluator: evaluates simple data structures, like expressions, in
7
Created 12/29/1997 Heikki Tuuri
8
*******************************************************/
10
#include "eval0eval.h"
13
#include "eval0eval.ic"
16
#include "data0data.h"
19
/* The RND function seed */
20
ulint eval_rnd = 128367121;
22
/* Dummy adress used when we should allocate a buffer of size 0 in
27
/*********************************************************************
28
Allocate a buffer from global dynamic memory for a value of a que_node.
29
NOTE that this memory must be explicitly freed when the query graph is
30
freed. If the node already has an allocated buffer, that buffer is freed
31
here. NOTE that this is the only function where dynamic memory should be
32
allocated for a query node val field. */
35
eval_node_alloc_val_buf(
36
/*====================*/
37
/* out: pointer to allocated buffer */
38
que_node_t* node, /* in: query graph node; sets the val field
39
data field to point to the new buffer, and
40
len field equal to size */
41
ulint size) /* in: buffer size */
46
ut_ad(que_node_get_type(node) == QUE_NODE_SYMBOL
47
|| que_node_get_type(node) == QUE_NODE_FUNC);
49
dfield = que_node_get_val(node);
51
data = dfield_get_data(dfield);
53
if (data && data != &eval_dummy) {
60
data = mem_alloc(size);
63
que_node_set_val_buf_size(node, size);
65
dfield_set_data(dfield, data, size);
70
/*********************************************************************
71
Free the buffer from global dynamic memory for a value of a que_node,
72
if it has been allocated in the above function. The freeing for pushed
73
column values is done in sel_col_prefetch_buf_free. */
76
eval_node_free_val_buf(
77
/*===================*/
78
que_node_t* node) /* in: query graph node */
83
ut_ad(que_node_get_type(node) == QUE_NODE_SYMBOL
84
|| que_node_get_type(node) == QUE_NODE_FUNC);
86
dfield = que_node_get_val(node);
88
data = dfield_get_data(dfield);
90
if (que_node_get_val_buf_size(node) > 0) {
97
/*********************************************************************
98
Evaluates a comparison node. */
103
/* out: the result of the comparison */
104
func_node_t* cmp_node) /* in: comparison node */
112
ut_ad(que_node_get_type(cmp_node) == QUE_NODE_FUNC);
114
arg1 = cmp_node->args;
115
arg2 = que_node_get_next(arg1);
117
res = cmp_dfield_dfield(que_node_get_val(arg1),
118
que_node_get_val(arg2));
121
func = cmp_node->func;
127
} else if (func == '<') {
131
} else if (func == PARS_LE_TOKEN) {
135
} else if (func == PARS_NE_TOKEN) {
139
} else if (func == PARS_GE_TOKEN) {
151
eval_node_set_ibool_val(cmp_node, val);
156
/*********************************************************************
157
Evaluates a logical operation node. */
162
func_node_t* logical_node) /* in: logical operation node */
167
ibool val2 = 0; /* remove warning */
168
ibool val = 0; /* remove warning */
171
ut_ad(que_node_get_type(logical_node) == QUE_NODE_FUNC);
173
arg1 = logical_node->args;
174
arg2 = que_node_get_next(arg1); /* arg2 is NULL if func is 'NOT' */
176
val1 = eval_node_get_ibool_val(arg1);
179
val2 = eval_node_get_ibool_val(arg2);
182
func = logical_node->func;
184
if (func == PARS_AND_TOKEN) {
186
} else if (func == PARS_OR_TOKEN) {
188
} else if (func == PARS_NOT_TOKEN) {
194
eval_node_set_ibool_val(logical_node, val);
197
/*********************************************************************
198
Evaluates an arithmetic operation node. */
203
func_node_t* arith_node) /* in: arithmetic operation node */
208
lint val2 = 0; /* remove warning */
212
ut_ad(que_node_get_type(arith_node) == QUE_NODE_FUNC);
214
arg1 = arith_node->args;
215
arg2 = que_node_get_next(arg1); /* arg2 is NULL if func is unary '-' */
217
val1 = eval_node_get_int_val(arg1);
220
val2 = eval_node_get_int_val(arg2);
223
func = arith_node->func;
227
} else if ((func == '-') && arg2) {
229
} else if (func == '-') {
231
} else if (func == '*') {
238
eval_node_set_int_val(arith_node, val);
241
/*********************************************************************
242
Evaluates an aggregate operation node. */
247
func_node_t* node) /* in: aggregate operation node */
254
ut_ad(que_node_get_type(node) == QUE_NODE_FUNC);
256
val = eval_node_get_int_val(node);
260
if (func == PARS_COUNT_TOKEN) {
264
ut_ad(func == PARS_SUM_TOKEN);
267
arg_val = eval_node_get_int_val(arg);
272
eval_node_set_int_val(node, val);
275
/*********************************************************************
276
Evaluates a predefined function node where the function is not relevant
282
func_node_t* func_node) /* in: predefined function node */
286
que_node_t* arg2 = 0; /* remove warning (??? bug ???) */
294
ut_ad(que_node_get_type(func_node) == QUE_NODE_FUNC);
296
arg1 = func_node->args;
299
arg2 = que_node_get_next(arg1);
302
func = func_node->func;
304
if (func == PARS_PRINTF_TOKEN) {
309
dfield_print(que_node_get_val(arg));
311
arg = que_node_get_next(arg);
316
} else if (func == PARS_ASSERT_TOKEN) {
318
if (!eval_node_get_ibool_val(arg1)) {
319
fputs("SQL assertion fails in a stored procedure!\n",
323
ut_a(eval_node_get_ibool_val(arg1));
325
/* This function, or more precisely, a debug procedure,
328
} else if (func == PARS_RND_TOKEN) {
330
len1 = (ulint)eval_node_get_int_val(arg1);
331
len2 = (ulint)eval_node_get_int_val(arg2);
336
int_val = (lint) (len1
337
+ (eval_rnd % (len2 - len1 + 1)));
339
int_val = (lint) len1;
342
eval_rnd = ut_rnd_gen_next_ulint(eval_rnd);
344
eval_node_set_int_val(func_node, int_val);
346
} else if (func == PARS_RND_STR_TOKEN) {
348
len1 = (ulint)eval_node_get_int_val(arg1);
350
data = eval_node_ensure_val_buf(func_node, len1);
352
for (i = 0; i < len1; i++) {
353
data[i] = (byte)(97 + (eval_rnd % 3));
355
eval_rnd = ut_rnd_gen_next_ulint(eval_rnd);
362
/*********************************************************************
363
Evaluates a notfound-function node. */
368
func_node_t* func_node) /* in: function node */
373
sel_node_t* sel_node;
376
arg1 = func_node->args;
377
arg2 = que_node_get_next(arg1);
379
ut_ad(func_node->func == PARS_NOTFOUND_TOKEN);
383
ut_ad(que_node_get_type(cursor) == QUE_NODE_SYMBOL);
385
if (cursor->token_type == SYM_LIT) {
387
ut_ad(ut_memcmp(dfield_get_data(que_node_get_val(cursor)),
390
sel_node = cursor->sym_table->query_graph->last_sel_node;
392
sel_node = cursor->alias->cursor_def;
395
if (sel_node->state == SEL_NODE_NO_MORE_ROWS) {
401
eval_node_set_ibool_val(func_node, ibool_val);
404
/*********************************************************************
405
Evaluates a substr-function node. */
410
func_node_t* func_node) /* in: function node */
420
arg1 = func_node->args;
421
arg2 = que_node_get_next(arg1);
423
ut_ad(func_node->func == PARS_SUBSTR_TOKEN);
425
arg3 = que_node_get_next(arg2);
427
str1 = dfield_get_data(que_node_get_val(arg1));
429
len1 = (ulint)eval_node_get_int_val(arg2);
430
len2 = (ulint)eval_node_get_int_val(arg3);
432
dfield = que_node_get_val(func_node);
434
dfield_set_data(dfield, str1 + len1, len2);
437
/*********************************************************************
438
Evaluates a replstr-procedure node. */
443
func_node_t* func_node) /* in: function node */
454
arg1 = func_node->args;
455
arg2 = que_node_get_next(arg1);
457
ut_ad(que_node_get_type(arg1) == QUE_NODE_SYMBOL);
459
arg3 = que_node_get_next(arg2);
460
arg4 = que_node_get_next(arg3);
462
str1 = dfield_get_data(que_node_get_val(arg1));
463
str2 = dfield_get_data(que_node_get_val(arg2));
465
len1 = (ulint)eval_node_get_int_val(arg3);
466
len2 = (ulint)eval_node_get_int_val(arg4);
468
if ((dfield_get_len(que_node_get_val(arg1)) < len1 + len2)
469
|| (dfield_get_len(que_node_get_val(arg2)) < len2)) {
474
ut_memcpy(str1 + len1, str2, len2);
477
/*********************************************************************
478
Evaluates an instr-function node. */
483
func_node_t* func_node) /* in: function node */
498
arg1 = func_node->args;
499
arg2 = que_node_get_next(arg1);
501
dfield1 = que_node_get_val(arg1);
502
dfield2 = que_node_get_val(arg2);
504
str1 = dfield_get_data(dfield1);
505
str2 = dfield_get_data(dfield2);
507
len1 = dfield_get_len(dfield1);
508
len2 = dfield_get_len(dfield2);
514
match_char = str2[0];
516
for (i = 0; i < len1; i++) {
517
/* In this outer loop, the number of matched characters is 0 */
519
if (str1[i] == match_char) {
521
if (i + len2 > len1) {
527
/* We have already matched j characters */
535
if (str1[i + j] != str2[j]) {
546
eval_node_set_int_val(func_node, int_val);
549
/*********************************************************************
550
Evaluates a predefined function node. */
553
eval_binary_to_number(
554
/*==================*/
555
func_node_t* func_node) /* in: function node */
564
arg1 = func_node->args;
566
dfield = que_node_get_val(arg1);
568
str1 = dfield_get_data(dfield);
569
len1 = dfield_get_len(dfield);
579
str2 = (byte*)&int_val;
581
ut_memcpy(str2 + (4 - len1), str1, len1);
584
eval_node_copy_and_alloc_val(func_node, str2, 4);
587
/*********************************************************************
588
Evaluates a predefined function node. */
593
func_node_t* func_node) /* in: function node */
601
arg = func_node->args;
605
len1 = dfield_get_len(que_node_get_val(arg));
609
arg = que_node_get_next(arg);
612
data = eval_node_ensure_val_buf(func_node, len);
614
arg = func_node->args;
618
dfield = que_node_get_val(arg);
619
len1 = dfield_get_len(dfield);
621
ut_memcpy(data + len, dfield_get_data(dfield), len1);
625
arg = que_node_get_next(arg);
629
/*********************************************************************
630
Evaluates a predefined function node. If the first argument is an integer,
631
this function looks at the second argument which is the integer length in
632
bytes, and converts the integer to a VARCHAR.
633
If the first argument is of some other type, this function converts it to
639
func_node_t* func_node) /* in: function node */
648
arg1 = func_node->args;
650
str1 = dfield_get_data(que_node_get_val(arg1));
652
if (dtype_get_mtype(que_node_get_data_type(arg1)) != DATA_INT) {
654
len = dfield_get_len(que_node_get_val(arg1));
656
dfield = que_node_get_val(func_node);
658
dfield_set_data(dfield, str1, len);
663
arg2 = que_node_get_next(arg1);
665
len1 = (ulint)eval_node_get_int_val(arg2);
672
dfield = que_node_get_val(func_node);
674
dfield_set_data(dfield, str1 + (4 - len1), len1);
677
/*********************************************************************
678
Evaluates a predefined function node. */
683
func_node_t* func_node) /* in: function node */
690
func = func_node->func;
692
arg1 = func_node->args;
694
if (func == PARS_LENGTH_TOKEN) {
696
int_val = (lint)dfield_get_len(que_node_get_val(arg1));
698
} else if (func == PARS_TO_CHAR_TOKEN) {
700
/* Convert number to character string as a
701
signed decimal integer. */
706
int_val = eval_node_get_int_val(arg1);
708
/* Determine the length of the string. */
711
int_len = 1; /* the number 0 occupies 1 byte */
715
uint_val = ((ulint) -int_val - 1) + 1;
716
int_len++; /* reserve space for minus sign */
718
uint_val = (ulint) int_val;
720
for (; uint_val > 0; int_len++) {
725
/* allocate the string */
726
data = eval_node_ensure_val_buf(func_node, int_len + 1);
728
/* add terminating NUL character */
731
/* convert the number */
738
data[0] = '-'; /* preceding minus sign */
739
uint_val = ((ulint) -int_val - 1) + 1;
741
uint_val = (ulint) int_val;
743
for (tmp = int_len; uint_val > 0; uint_val /= 10) {
745
('0' + (byte)(uint_val % 10));
749
dfield_set_len((dfield_t*) que_node_get_val(func_node),
754
} else if (func == PARS_TO_NUMBER_TOKEN) {
756
int_val = atoi((char*)
757
dfield_get_data(que_node_get_val(arg1)));
759
} else if (func == PARS_SYSDATE_TOKEN) {
760
int_val = (lint)ut_time();
762
eval_predefined_2(func_node);
767
eval_node_set_int_val(func_node, int_val);
770
/*********************************************************************
771
Evaluates a function node. */
776
func_node_t* func_node) /* in: function node */
782
ut_ad(que_node_get_type(func_node) == QUE_NODE_FUNC);
784
class = func_node->class;
785
func = func_node->func;
787
arg = func_node->args;
789
/* Evaluate first the argument list */
793
/* The functions are not defined for SQL null argument
794
values, except for eval_cmp and notfound */
796
if ((dfield_get_len(que_node_get_val(arg)) == UNIV_SQL_NULL)
797
&& (class != PARS_FUNC_CMP)
798
&& (func != PARS_NOTFOUND_TOKEN)
799
&& (func != PARS_PRINTF_TOKEN)) {
803
arg = que_node_get_next(arg);
806
if (class == PARS_FUNC_CMP) {
808
} else if (class == PARS_FUNC_ARITH) {
809
eval_arith(func_node);
810
} else if (class == PARS_FUNC_AGGREGATE) {
811
eval_aggregate(func_node);
812
} else if (class == PARS_FUNC_PREDEFINED) {
814
if (func == PARS_NOTFOUND_TOKEN) {
815
eval_notfound(func_node);
816
} else if (func == PARS_SUBSTR_TOKEN) {
817
eval_substr(func_node);
818
} else if (func == PARS_REPLSTR_TOKEN) {
819
eval_replstr(func_node);
820
} else if (func == PARS_INSTR_TOKEN) {
821
eval_instr(func_node);
822
} else if (func == PARS_BINARY_TO_NUMBER_TOKEN) {
823
eval_binary_to_number(func_node);
824
} else if (func == PARS_CONCAT_TOKEN) {
825
eval_concat(func_node);
826
} else if (func == PARS_TO_BINARY_TOKEN) {
827
eval_to_binary(func_node);
829
eval_predefined(func_node);
832
ut_ad(class == PARS_FUNC_LOGICAL);
834
eval_logical(func_node);