1
/*****************************************************************************
3
Copyright (C) 1997, 2009, Innobase Oy. All Rights Reserved.
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.
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.
13
You should have received a copy of the GNU General Public License along with
14
this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
15
St, Fifth Floor, Boston, MA 02110-1301 USA
17
*****************************************************************************/
19
/**************************************************//**
20
@file eval/eval0eval.c
21
SQL evaluator: evaluates simple data structures, like expressions, in
24
Created 12/29/1997 Heikki Tuuri
25
*******************************************************/
27
#include "eval0eval.h"
30
#include "eval0eval.ic"
33
#include "data0data.h"
36
/** The RND function seed */
37
static ulint eval_rnd = 128367121;
39
/** Dummy adress used when we should allocate a buffer of size 0 in
40
eval_node_alloc_val_buf */
42
static byte eval_dummy;
44
/*****************************************************************//**
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
49
allocated for a query node val field.
50
@return pointer to allocated buffer */
53
eval_node_alloc_val_buf(
54
/*====================*/
55
que_node_t* node, /*!< in: query graph node; sets the val field
56
data field to point to the new buffer, and
57
len field equal to size */
58
ulint size) /*!< in: buffer size */
63
ut_ad(que_node_get_type(node) == QUE_NODE_SYMBOL
64
|| que_node_get_type(node) == QUE_NODE_FUNC);
66
dfield = que_node_get_val(node);
68
data = static_cast<unsigned char *>(dfield_get_data(dfield));
70
if (data && data != &eval_dummy) {
77
data = static_cast<unsigned char *>(mem_alloc(size));
80
que_node_set_val_buf_size(node, size);
82
dfield_set_data(dfield, data, size);
87
/*****************************************************************//**
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. */
93
eval_node_free_val_buf(
94
/*===================*/
95
que_node_t* node) /*!< in: query graph node */
100
ut_ad(que_node_get_type(node) == QUE_NODE_SYMBOL
101
|| que_node_get_type(node) == QUE_NODE_FUNC);
103
dfield = que_node_get_val(node);
105
data = static_cast<unsigned char *>(dfield_get_data(dfield));
107
if (que_node_get_val_buf_size(node) > 0) {
114
/*****************************************************************//**
115
Evaluates a comparison node.
116
@return the result of the comparison */
121
func_node_t* cmp_node) /*!< in: comparison node */
129
ut_ad(que_node_get_type(cmp_node) == QUE_NODE_FUNC);
131
arg1 = cmp_node->args;
132
arg2 = que_node_get_next(arg1);
134
res = cmp_dfield_dfield(que_node_get_val(arg1),
135
que_node_get_val(arg2));
138
func = cmp_node->func;
144
} else if (func == '<') {
148
} else if (func == PARS_LE_TOKEN) {
152
} else if (func == PARS_NE_TOKEN) {
156
} else if (func == PARS_GE_TOKEN) {
168
eval_node_set_ibool_val(cmp_node, val);
173
/*****************************************************************//**
174
Evaluates a logical operation node. */
179
func_node_t* logical_node) /*!< in: logical operation node */
184
ibool val2 = 0; /* remove warning */
185
ibool val = 0; /* remove warning */
188
ut_ad(que_node_get_type(logical_node) == QUE_NODE_FUNC);
190
arg1 = logical_node->args;
191
arg2 = que_node_get_next(arg1); /* arg2 is NULL if func is 'NOT' */
193
val1 = eval_node_get_ibool_val(arg1);
196
val2 = eval_node_get_ibool_val(arg2);
199
func = logical_node->func;
201
if (func == PARS_AND_TOKEN) {
203
} else if (func == PARS_OR_TOKEN) {
205
} else if (func == PARS_NOT_TOKEN) {
211
eval_node_set_ibool_val(logical_node, val);
214
/*****************************************************************//**
215
Evaluates an arithmetic operation node. */
220
func_node_t* arith_node) /*!< in: arithmetic operation node */
225
lint val2 = 0; /* remove warning */
229
ut_ad(que_node_get_type(arith_node) == QUE_NODE_FUNC);
231
arg1 = arith_node->args;
232
arg2 = que_node_get_next(arg1); /* arg2 is NULL if func is unary '-' */
234
val1 = eval_node_get_int_val(arg1);
237
val2 = eval_node_get_int_val(arg2);
240
func = arith_node->func;
244
} else if ((func == '-') && arg2) {
246
} else if (func == '-') {
248
} else if (func == '*') {
255
eval_node_set_int_val(arith_node, val);
258
/*****************************************************************//**
259
Evaluates an aggregate operation node. */
264
func_node_t* node) /*!< in: aggregate operation node */
271
ut_ad(que_node_get_type(node) == QUE_NODE_FUNC);
273
val = eval_node_get_int_val(node);
277
if (func == PARS_COUNT_TOKEN) {
281
ut_ad(func == PARS_SUM_TOKEN);
284
arg_val = eval_node_get_int_val(arg);
289
eval_node_set_int_val(node, val);
292
/*****************************************************************//**
293
Evaluates a predefined function node where the function is not relevant
299
func_node_t* func_node) /*!< in: predefined function node */
303
que_node_t* arg2 = 0; /* remove warning (??? bug ???) */
311
ut_ad(que_node_get_type(func_node) == QUE_NODE_FUNC);
313
arg1 = func_node->args;
316
arg2 = que_node_get_next(arg1);
319
func = func_node->func;
321
if (func == PARS_PRINTF_TOKEN) {
326
dfield_print(que_node_get_val(arg));
328
arg = que_node_get_next(arg);
333
} else if (func == PARS_ASSERT_TOKEN) {
335
if (!eval_node_get_ibool_val(arg1)) {
336
fputs("SQL assertion fails in a stored procedure!\n",
340
ut_a(eval_node_get_ibool_val(arg1));
342
/* This function, or more precisely, a debug procedure,
345
} else if (func == PARS_RND_TOKEN) {
347
len1 = (ulint)eval_node_get_int_val(arg1);
348
len2 = (ulint)eval_node_get_int_val(arg2);
353
int_val = (lint) (len1
354
+ (eval_rnd % (len2 - len1 + 1)));
356
int_val = (lint) len1;
359
eval_rnd = ut_rnd_gen_next_ulint(eval_rnd);
361
eval_node_set_int_val(func_node, int_val);
363
} else if (func == PARS_RND_STR_TOKEN) {
365
len1 = (ulint)eval_node_get_int_val(arg1);
367
data = eval_node_ensure_val_buf(func_node, len1);
369
for (i = 0; i < len1; i++) {
370
data[i] = (byte)(97 + (eval_rnd % 3));
372
eval_rnd = ut_rnd_gen_next_ulint(eval_rnd);
379
/*****************************************************************//**
380
Evaluates a notfound-function node. */
385
func_node_t* func_node) /*!< in: function node */
388
sel_node_t* sel_node;
391
ut_ad(func_node->func == PARS_NOTFOUND_TOKEN);
393
cursor = static_cast<sym_node_t *>(func_node->args);
395
ut_ad(que_node_get_type(cursor) == QUE_NODE_SYMBOL);
397
if (cursor->token_type == SYM_LIT) {
399
ut_ad(ut_memcmp(dfield_get_data(que_node_get_val(cursor)),
402
sel_node = cursor->sym_table->query_graph->last_sel_node;
404
sel_node = cursor->alias->cursor_def;
407
if (sel_node->state == SEL_NODE_NO_MORE_ROWS) {
413
eval_node_set_ibool_val(func_node, ibool_val);
416
/*****************************************************************//**
417
Evaluates a substr-function node. */
422
func_node_t* func_node) /*!< in: function node */
432
arg1 = func_node->args;
433
arg2 = que_node_get_next(arg1);
435
ut_ad(func_node->func == PARS_SUBSTR_TOKEN);
437
arg3 = que_node_get_next(arg2);
439
str1 = static_cast<unsigned char *>(dfield_get_data(que_node_get_val(arg1)));
441
len1 = (ulint)eval_node_get_int_val(arg2);
442
len2 = (ulint)eval_node_get_int_val(arg3);
444
dfield = que_node_get_val(func_node);
446
dfield_set_data(dfield, str1 + len1, len2);
449
/*****************************************************************//**
450
Evaluates a replstr-procedure node. */
455
func_node_t* func_node) /*!< in: function node */
466
arg1 = func_node->args;
467
arg2 = que_node_get_next(arg1);
469
ut_ad(que_node_get_type(arg1) == QUE_NODE_SYMBOL);
471
arg3 = que_node_get_next(arg2);
472
arg4 = que_node_get_next(arg3);
474
str1 = static_cast<unsigned char *>(dfield_get_data(que_node_get_val(arg1)));
475
str2 = static_cast<unsigned char *>(dfield_get_data(que_node_get_val(arg2)));
477
len1 = (ulint)eval_node_get_int_val(arg3);
478
len2 = (ulint)eval_node_get_int_val(arg4);
480
if ((dfield_get_len(que_node_get_val(arg1)) < len1 + len2)
481
|| (dfield_get_len(que_node_get_val(arg2)) < len2)) {
486
ut_memcpy(str1 + len1, str2, len2);
489
/*****************************************************************//**
490
Evaluates an instr-function node. */
495
func_node_t* func_node) /*!< in: function node */
510
arg1 = func_node->args;
511
arg2 = que_node_get_next(arg1);
513
dfield1 = que_node_get_val(arg1);
514
dfield2 = que_node_get_val(arg2);
516
str1 = static_cast<unsigned char *>(dfield_get_data(dfield1));
517
str2 = static_cast<unsigned char *>(dfield_get_data(dfield2));
519
len1 = dfield_get_len(dfield1);
520
len2 = dfield_get_len(dfield2);
526
match_char = str2[0];
528
for (i = 0; i < len1; i++) {
529
/* In this outer loop, the number of matched characters is 0 */
531
if (str1[i] == match_char) {
533
if (i + len2 > len1) {
539
/* We have already matched j characters */
547
if (str1[i + j] != str2[j]) {
558
eval_node_set_int_val(func_node, int_val);
561
/*****************************************************************//**
562
Evaluates a predefined function node. */
565
eval_binary_to_number(
566
/*==================*/
567
func_node_t* func_node) /*!< in: function node */
576
arg1 = func_node->args;
578
dfield = que_node_get_val(arg1);
580
str1 = static_cast<unsigned char *>(dfield_get_data(dfield));
581
len1 = dfield_get_len(dfield);
591
str2 = (byte*)&int_val;
593
ut_memcpy(str2 + (4 - len1), str1, len1);
596
eval_node_copy_and_alloc_val(func_node, str2, 4);
599
/*****************************************************************//**
600
Evaluates a predefined function node. */
605
func_node_t* func_node) /*!< in: function node */
613
arg = func_node->args;
617
len1 = dfield_get_len(que_node_get_val(arg));
621
arg = que_node_get_next(arg);
624
data = eval_node_ensure_val_buf(func_node, len);
626
arg = func_node->args;
630
dfield = que_node_get_val(arg);
631
len1 = dfield_get_len(dfield);
633
ut_memcpy(data + len, dfield_get_data(dfield), len1);
637
arg = que_node_get_next(arg);
641
/*****************************************************************//**
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
651
func_node_t* func_node) /*!< in: function node */
660
arg1 = func_node->args;
662
str1 = static_cast<unsigned char *>(dfield_get_data(que_node_get_val(arg1)));
664
if (dtype_get_mtype(que_node_get_data_type(arg1)) != DATA_INT) {
666
len = dfield_get_len(que_node_get_val(arg1));
668
dfield = que_node_get_val(func_node);
670
dfield_set_data(dfield, str1, len);
675
arg2 = que_node_get_next(arg1);
677
len1 = (ulint)eval_node_get_int_val(arg2);
684
dfield = que_node_get_val(func_node);
686
dfield_set_data(dfield, str1 + (4 - len1), len1);
689
/*****************************************************************//**
690
Evaluates a predefined function node. */
695
func_node_t* func_node) /*!< in: function node */
702
func = func_node->func;
704
arg1 = func_node->args;
706
if (func == PARS_LENGTH_TOKEN) {
708
int_val = (lint)dfield_get_len(que_node_get_val(arg1));
710
} else if (func == PARS_TO_CHAR_TOKEN) {
712
/* Convert number to character string as a
713
signed decimal integer. */
718
int_val = eval_node_get_int_val(arg1);
720
/* Determine the length of the string. */
723
int_len = 1; /* the number 0 occupies 1 byte */
727
uint_val = ((ulint) -int_val - 1) + 1;
728
int_len++; /* reserve space for minus sign */
730
uint_val = (ulint) int_val;
732
for (; uint_val > 0; int_len++) {
737
/* allocate the string */
738
data = eval_node_ensure_val_buf(func_node, int_len + 1);
740
/* add terminating NUL character */
743
/* convert the number */
750
data[0] = '-'; /* preceding minus sign */
751
uint_val = ((ulint) -int_val - 1) + 1;
753
uint_val = (ulint) int_val;
755
for (tmp = int_len; uint_val > 0; uint_val /= 10) {
757
('0' + (byte)(uint_val % 10));
761
dfield_set_len(que_node_get_val(func_node), int_len);
765
} else if (func == PARS_TO_NUMBER_TOKEN) {
767
int_val = atoi((char*)
768
dfield_get_data(que_node_get_val(arg1)));
770
} else if (func == PARS_SYSDATE_TOKEN) {
771
int_val = (lint)ut_time();
773
eval_predefined_2(func_node);
778
eval_node_set_int_val(func_node, int_val);
781
/*****************************************************************//**
782
Evaluates a function node. */
787
func_node_t* func_node) /*!< in: function node */
793
ut_ad(que_node_get_type(func_node) == QUE_NODE_FUNC);
795
func_class = func_node->func_class;
796
func = func_node->func;
798
arg = func_node->args;
800
/* Evaluate first the argument list */
804
/* The functions are not defined for SQL null argument
805
values, except for eval_cmp and notfound */
807
if (dfield_is_null(que_node_get_val(arg))
808
&& (func_class != PARS_FUNC_CMP)
809
&& (func != PARS_NOTFOUND_TOKEN)
810
&& (func != PARS_PRINTF_TOKEN)) {
814
arg = que_node_get_next(arg);
817
if (func_class == PARS_FUNC_CMP) {
819
} else if (func_class == PARS_FUNC_ARITH) {
820
eval_arith(func_node);
821
} else if (func_class == PARS_FUNC_AGGREGATE) {
822
eval_aggregate(func_node);
823
} else if (func_class == PARS_FUNC_PREDEFINED) {
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);
840
eval_predefined(func_node);
843
ut_ad(func_class == PARS_FUNC_LOGICAL);
845
eval_logical(func_node);