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.,
15 51 Franklin 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
= dfield_get_data(dfield
);
70 if (data
&& data
!= &eval_dummy
) {
77 data
= 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
= 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
= 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
= 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
= dfield_get_data(que_node_get_val(arg1
));
475 str2
= 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
= dfield_get_data(dfield1
);
517 str2
= 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
= 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
= 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 class = func_node
->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 && (class != PARS_FUNC_CMP
)
809 && (func
!= PARS_NOTFOUND_TOKEN
)
810 && (func
!= PARS_PRINTF_TOKEN
)) {
814 arg
= que_node_get_next(arg
);
817 if (class == PARS_FUNC_CMP
) {
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
) {
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(class == PARS_FUNC_LOGICAL
);
845 eval_logical(func_node
);