MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
eval0eval.cc
Go to the documentation of this file.
1 /*****************************************************************************
2 
3 Copyright (c) 1997, 2011, Oracle and/or its affiliates. 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
14 this program; if not, write to the Free Software Foundation, Inc.,
15 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
16 
17 *****************************************************************************/
18 
19 /**************************************************/
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 #include "rem0cmp.h"
36 
38 static ulint eval_rnd = 128367121;
39 
43 static byte eval_dummy;
44 
45 /*************************************************************************
46 Gets the like node from the node */
47 UNIV_INLINE
48 que_node_t*
49 que_node_get_like_node(
50 /*===================*/
51  /* out: next node in a list of nodes */
52  que_node_t* node) /* in: node in a list */
53 {
54  return(((sym_node_t*) node)->like_node);
55 }
56 
57 /*****************************************************************/
64 UNIV_INTERN
65 byte*
67 /*====================*/
68  que_node_t* node,
71  ulint size)
72 {
73  dfield_t* dfield;
74  byte* data;
75 
76  ut_ad(que_node_get_type(node) == QUE_NODE_SYMBOL
77  || que_node_get_type(node) == QUE_NODE_FUNC);
78 
79  dfield = que_node_get_val(node);
80 
81  data = static_cast<byte*>(dfield_get_data(dfield));
82 
83  if (data && data != &eval_dummy) {
84  mem_free(data);
85  }
86 
87  if (size == 0) {
88  data = &eval_dummy;
89  } else {
90  data = static_cast<byte*>(mem_alloc(size));
91  }
92 
93  que_node_set_val_buf_size(node, size);
94 
95  dfield_set_data(dfield, data, size);
96 
97  return(data);
98 }
99 
100 /*****************************************************************/
104 UNIV_INTERN
105 void
107 /*===================*/
108  que_node_t* node)
109 {
110  dfield_t* dfield;
111  byte* data;
112 
113  ut_ad(que_node_get_type(node) == QUE_NODE_SYMBOL
114  || que_node_get_type(node) == QUE_NODE_FUNC);
115 
116  dfield = que_node_get_val(node);
117 
118  data = static_cast<byte*>(dfield_get_data(dfield));
119 
120  if (que_node_get_val_buf_size(node) > 0) {
121  ut_a(data);
122 
123  mem_free(data);
124  }
125 }
126 
127 /*********************************************************************
128 Evaluates a LIKE comparison node.
129 @return the result of the comparison */
130 UNIV_INLINE
131 ibool
132 eval_cmp_like(
133 /*==========*/
134  que_node_t* arg1, /* !< in: left operand */
135  que_node_t* arg2) /* !< in: right operand */
136 {
137  ib_like_t op;
138  int res;
139  que_node_t* arg3;
140  que_node_t* arg4;
141  dfield_t* dfield;
142  dtype_t* dtype;
143  ibool val = TRUE;
144 
145  arg3 = que_node_get_like_node(arg2);
146 
147  /* Get the comparison type operator */
148  ut_a(arg3);
149 
150  dfield = que_node_get_val(arg3);
151  dtype = dfield_get_type(dfield);
152 
153  ut_a(dtype_get_mtype(dtype) == DATA_INT);
154  op = static_cast<ib_like_t>(mach_read_from_4(static_cast<const unsigned char*>(dfield_get_data(dfield))));
155 
156  switch (op) {
157  case IB_LIKE_PREFIX:
158 
159  arg4 = que_node_get_next(arg3);
160  res = cmp_dfield_dfield_like_prefix(
161  que_node_get_val(arg1),
162  que_node_get_val(arg4));
163  break;
164 
165  case IB_LIKE_SUFFIX:
166 
167  arg4 = que_node_get_next(arg3);
168  res = cmp_dfield_dfield_like_suffix(
169  que_node_get_val(arg1),
170  que_node_get_val(arg4));
171  break;
172 
173  case IB_LIKE_SUBSTR:
174 
175  arg4 = que_node_get_next(arg3);
176  res = cmp_dfield_dfield_like_substr(
177  que_node_get_val(arg1),
178  que_node_get_val(arg4));
179  break;
180 
181  case IB_LIKE_EXACT:
182  res = cmp_dfield_dfield(
183  que_node_get_val(arg1),
184  que_node_get_val(arg2));
185  break;
186 
187  default:
188  ut_error;
189  }
190 
191  if (res != 0) {
192  val = FALSE;
193  }
194 
195  return(val);
196 }
197 
198 /*********************************************************************
199 Evaluates a comparison node.
200 @return the result of the comparison */
201 ibool
203 /*=====*/
204  func_node_t* cmp_node)
205 {
206  que_node_t* arg1;
207  que_node_t* arg2;
208  int res;
209  int func;
210  ibool val = TRUE;
211 
212  ut_ad(que_node_get_type(cmp_node) == QUE_NODE_FUNC);
213 
214  arg1 = cmp_node->args;
215  arg2 = que_node_get_next(arg1);
216 
217  func = cmp_node->func;
218 
219  if (func == PARS_LIKE_TOKEN_EXACT
220  || func == PARS_LIKE_TOKEN_PREFIX
221  || func == PARS_LIKE_TOKEN_SUFFIX
222  || func == PARS_LIKE_TOKEN_SUBSTR) {
223 
224  val = eval_cmp_like(arg1, arg2);
225  } else {
226  res = cmp_dfield_dfield(
227  que_node_get_val(arg1), que_node_get_val(arg2));
228 
229  if (func == '=') {
230  if (res != 0) {
231  val = FALSE;
232  }
233  } else if (func == '<') {
234  if (res != -1) {
235  val = FALSE;
236  }
237  } else if (func == PARS_LE_TOKEN) {
238  if (res == 1) {
239  val = FALSE;
240  }
241  } else if (func == PARS_NE_TOKEN) {
242  if (res == 0) {
243  val = FALSE;
244  }
245  } else if (func == PARS_GE_TOKEN) {
246  if (res == -1) {
247  val = FALSE;
248  }
249  } else {
250  ut_ad(func == '>');
251 
252  if (res != 1) {
253  val = FALSE;
254  }
255  }
256  }
257 
258  eval_node_set_ibool_val(cmp_node, val);
259 
260  return(val);
261 }
262 
263 /*****************************************************************/
265 UNIV_INLINE
266 void
268 /*=========*/
269  func_node_t* logical_node)
270 {
271  que_node_t* arg1;
272  que_node_t* arg2;
273  ibool val1;
274  ibool val2 = 0; /* remove warning */
275  ibool val = 0; /* remove warning */
276  int func;
277 
278  ut_ad(que_node_get_type(logical_node) == QUE_NODE_FUNC);
279 
280  arg1 = logical_node->args;
281  arg2 = que_node_get_next(arg1); /* arg2 is NULL if func is 'NOT' */
282 
283  val1 = eval_node_get_ibool_val(arg1);
284 
285  if (arg2) {
286  val2 = eval_node_get_ibool_val(arg2);
287  }
288 
289  func = logical_node->func;
290 
291  if (func == PARS_AND_TOKEN) {
292  val = val1 & val2;
293  } else if (func == PARS_OR_TOKEN) {
294  val = val1 | val2;
295  } else if (func == PARS_NOT_TOKEN) {
296  val = TRUE - val1;
297  } else {
298  ut_error;
299  }
300 
301  eval_node_set_ibool_val(logical_node, val);
302 }
303 
304 /*****************************************************************/
306 UNIV_INLINE
307 void
309 /*=======*/
310  func_node_t* arith_node)
311 {
312  que_node_t* arg1;
313  que_node_t* arg2;
314  lint val1;
315  lint val2 = 0; /* remove warning */
316  lint val;
317  int func;
318 
319  ut_ad(que_node_get_type(arith_node) == QUE_NODE_FUNC);
320 
321  arg1 = arith_node->args;
322  arg2 = que_node_get_next(arg1); /* arg2 is NULL if func is unary '-' */
323 
324  val1 = eval_node_get_int_val(arg1);
325 
326  if (arg2) {
327  val2 = eval_node_get_int_val(arg2);
328  }
329 
330  func = arith_node->func;
331 
332  if (func == '+') {
333  val = val1 + val2;
334  } else if ((func == '-') && arg2) {
335  val = val1 - val2;
336  } else if (func == '-') {
337  val = -val1;
338  } else if (func == '*') {
339  val = val1 * val2;
340  } else {
341  ut_ad(func == '/');
342  val = val1 / val2;
343  }
344 
345  eval_node_set_int_val(arith_node, val);
346 }
347 
348 /*****************************************************************/
350 UNIV_INLINE
351 void
353 /*===========*/
354  func_node_t* node)
355 {
356  que_node_t* arg;
357  lint val;
358  lint arg_val;
359  int func;
360 
361  ut_ad(que_node_get_type(node) == QUE_NODE_FUNC);
362 
363  val = eval_node_get_int_val(node);
364 
365  func = node->func;
366 
367  if (func == PARS_COUNT_TOKEN) {
368 
369  val = val + 1;
370  } else {
371  ut_ad(func == PARS_SUM_TOKEN);
372 
373  arg = node->args;
374  arg_val = eval_node_get_int_val(arg);
375 
376  val = val + arg_val;
377  }
378 
379  eval_node_set_int_val(node, val);
380 }
381 
382 /*****************************************************************/
385 static
386 void
387 eval_predefined_2(
388 /*==============*/
389  func_node_t* func_node)
390 {
391  que_node_t* arg;
392  que_node_t* arg1;
393  que_node_t* arg2 = 0; /* remove warning (??? bug ???) */
394  lint int_val;
395  byte* data;
396  ulint len1;
397  ulint len2;
398  int func;
399  ulint i;
400 
401  ut_ad(que_node_get_type(func_node) == QUE_NODE_FUNC);
402 
403  arg1 = func_node->args;
404 
405  if (arg1) {
406  arg2 = que_node_get_next(arg1);
407  }
408 
409  func = func_node->func;
410 
411  if (func == PARS_PRINTF_TOKEN) {
412 
413  arg = arg1;
414 
415  while (arg) {
417 
418  arg = que_node_get_next(arg);
419  }
420 
421  putc('\n', stderr);
422 
423  } else if (func == PARS_ASSERT_TOKEN) {
424 
425  if (!eval_node_get_ibool_val(arg1)) {
426  fputs("SQL assertion fails in a stored procedure!\n",
427  stderr);
428  }
429 
431 
432  /* This function, or more precisely, a debug procedure,
433  returns no value */
434 
435  } else if (func == PARS_RND_TOKEN) {
436 
437  len1 = (ulint) eval_node_get_int_val(arg1);
438  len2 = (ulint) eval_node_get_int_val(arg2);
439 
440  ut_ad(len2 >= len1);
441 
442  if (len2 > len1) {
443  int_val = (lint) (len1
444  + (eval_rnd % (len2 - len1 + 1)));
445  } else {
446  int_val = (lint) len1;
447  }
448 
449  eval_rnd = ut_rnd_gen_next_ulint(eval_rnd);
450 
451  eval_node_set_int_val(func_node, int_val);
452 
453  } else if (func == PARS_RND_STR_TOKEN) {
454 
455  len1 = (ulint) eval_node_get_int_val(arg1);
456 
457  data = eval_node_ensure_val_buf(func_node, len1);
458 
459  for (i = 0; i < len1; i++) {
460  data[i] = (byte)(97 + (eval_rnd % 3));
461 
462  eval_rnd = ut_rnd_gen_next_ulint(eval_rnd);
463  }
464  } else {
465  ut_error;
466  }
467 }
468 
469 /*****************************************************************/
471 UNIV_INLINE
472 void
474 /*==========*/
475  func_node_t* func_node)
476 {
478  sel_node_t* sel_node;
479  ibool ibool_val;
480 
481  ut_ad(func_node->func == PARS_NOTFOUND_TOKEN);
482 
483  cursor = static_cast<sym_node_t*>(func_node->args);
484 
485  ut_ad(que_node_get_type(cursor) == QUE_NODE_SYMBOL);
486 
487  if (cursor->token_type == SYM_LIT) {
488 
489  ut_ad(ut_memcmp(dfield_get_data(que_node_get_val(cursor)),
490  "SQL", 3) == 0);
491 
492  sel_node = cursor->sym_table->query_graph->last_sel_node;
493  } else {
494  sel_node = cursor->alias->cursor_def;
495  }
496 
497  if (sel_node->state == SEL_NODE_NO_MORE_ROWS) {
498  ibool_val = TRUE;
499  } else {
500  ibool_val = FALSE;
501  }
502 
503  eval_node_set_ibool_val(func_node, ibool_val);
504 }
505 
506 /*****************************************************************/
508 UNIV_INLINE
509 void
511 /*========*/
512  func_node_t* func_node)
513 {
514  que_node_t* arg1;
515  que_node_t* arg2;
516  que_node_t* arg3;
517  dfield_t* dfield;
518  byte* str1;
519  ulint len1;
520  ulint len2;
521 
522  arg1 = func_node->args;
523  arg2 = que_node_get_next(arg1);
524 
525  ut_ad(func_node->func == PARS_SUBSTR_TOKEN);
526 
527  arg3 = que_node_get_next(arg2);
528 
529  str1 = static_cast<byte*>(dfield_get_data(que_node_get_val(arg1)));
530 
531  len1 = (ulint) eval_node_get_int_val(arg2);
532  len2 = (ulint) eval_node_get_int_val(arg3);
533 
534  dfield = que_node_get_val(func_node);
535 
536  dfield_set_data(dfield, str1 + len1, len2);
537 }
538 
539 /*****************************************************************/
541 static
542 void
543 eval_replstr(
544 /*=========*/
545  func_node_t* func_node)
546 {
547  que_node_t* arg1;
548  que_node_t* arg2;
549  que_node_t* arg3;
550  que_node_t* arg4;
551  byte* str1;
552  byte* str2;
553  ulint len1;
554  ulint len2;
555 
556  arg1 = func_node->args;
557  arg2 = que_node_get_next(arg1);
558 
559  ut_ad(que_node_get_type(arg1) == QUE_NODE_SYMBOL);
560 
561  arg3 = que_node_get_next(arg2);
562  arg4 = que_node_get_next(arg3);
563 
564  str1 = static_cast<byte*>(dfield_get_data(que_node_get_val(arg1)));
565  str2 = static_cast<byte*>(dfield_get_data(que_node_get_val(arg2)));
566 
567  len1 = (ulint) eval_node_get_int_val(arg3);
568  len2 = (ulint) eval_node_get_int_val(arg4);
569 
570  if ((dfield_get_len(que_node_get_val(arg1)) < len1 + len2)
571  || (dfield_get_len(que_node_get_val(arg2)) < len2)) {
572 
573  ut_error;
574  }
575 
576  ut_memcpy(str1 + len1, str2, len2);
577 }
578 
579 /*****************************************************************/
581 static
582 void
583 eval_instr(
584 /*=======*/
585  func_node_t* func_node)
586 {
587  que_node_t* arg1;
588  que_node_t* arg2;
589  dfield_t* dfield1;
590  dfield_t* dfield2;
591  lint int_val;
592  byte* str1;
593  byte* str2;
594  byte match_char;
595  ulint len1;
596  ulint len2;
597  ulint i;
598  ulint j;
599 
600  arg1 = func_node->args;
601  arg2 = que_node_get_next(arg1);
602 
603  dfield1 = que_node_get_val(arg1);
604  dfield2 = que_node_get_val(arg2);
605 
606  str1 = static_cast<byte*>(dfield_get_data(dfield1));
607  str2 = static_cast<byte*>(dfield_get_data(dfield2));
608 
609  len1 = dfield_get_len(dfield1);
610  len2 = dfield_get_len(dfield2);
611 
612  if (len2 == 0) {
613  ut_error;
614  }
615 
616  match_char = str2[0];
617 
618  for (i = 0; i < len1; i++) {
619  /* In this outer loop, the number of matched characters is 0 */
620 
621  if (str1[i] == match_char) {
622 
623  if (i + len2 > len1) {
624 
625  break;
626  }
627 
628  for (j = 1;; j++) {
629  /* We have already matched j characters */
630 
631  if (j == len2) {
632  int_val = i + 1;
633 
634  goto match_found;
635  }
636 
637  if (str1[i + j] != str2[j]) {
638 
639  break;
640  }
641  }
642  }
643  }
644 
645  int_val = 0;
646 
647 match_found:
648  eval_node_set_int_val(func_node, int_val);
649 }
650 
651 /*****************************************************************/
653 UNIV_INLINE
654 void
656 /*==================*/
657  func_node_t* func_node)
658 {
659  que_node_t* arg1;
660  dfield_t* dfield;
661  byte* str1;
662  byte* str2;
663  ulint len1;
664  ulint int_val;
665 
666  arg1 = func_node->args;
667 
668  dfield = que_node_get_val(arg1);
669 
670  str1 = static_cast<byte*>(dfield_get_data(dfield));
671  len1 = dfield_get_len(dfield);
672 
673  if (len1 > 4) {
674  ut_error;
675  }
676 
677  if (len1 == 4) {
678  str2 = str1;
679  } else {
680  int_val = 0;
681  str2 = (byte*) &int_val;
682 
683  ut_memcpy(str2 + (4 - len1), str1, len1);
684  }
685 
686  eval_node_copy_and_alloc_val(func_node, str2, 4);
687 }
688 
689 /*****************************************************************/
691 static
692 void
693 eval_concat(
694 /*========*/
695  func_node_t* func_node)
696 {
697  que_node_t* arg;
698  dfield_t* dfield;
699  byte* data;
700  ulint len;
701  ulint len1;
702 
703  arg = func_node->args;
704  len = 0;
705 
706  while (arg) {
707  len1 = dfield_get_len(que_node_get_val(arg));
708 
709  len += len1;
710 
711  arg = que_node_get_next(arg);
712  }
713 
714  data = eval_node_ensure_val_buf(func_node, len);
715 
716  arg = func_node->args;
717  len = 0;
718 
719  while (arg) {
720  dfield = que_node_get_val(arg);
721  len1 = dfield_get_len(dfield);
722 
723  ut_memcpy(data + len, dfield_get_data(dfield), len1);
724 
725  len += len1;
726 
727  arg = que_node_get_next(arg);
728  }
729 }
730 
731 /*****************************************************************/
737 UNIV_INLINE
738 void
740 /*===========*/
741  func_node_t* func_node)
742 {
743  que_node_t* arg1;
744  que_node_t* arg2;
745  dfield_t* dfield;
746  byte* str1;
747  ulint len;
748  ulint len1;
749 
750  arg1 = func_node->args;
751 
752  str1 = static_cast<byte*>(dfield_get_data(que_node_get_val(arg1)));
753 
754  if (dtype_get_mtype(que_node_get_data_type(arg1)) != DATA_INT) {
755 
756  len = dfield_get_len(que_node_get_val(arg1));
757 
758  dfield = que_node_get_val(func_node);
759 
760  dfield_set_data(dfield, str1, len);
761 
762  return;
763  }
764 
765  arg2 = que_node_get_next(arg1);
766 
767  len1 = (ulint) eval_node_get_int_val(arg2);
768 
769  if (len1 > 4) {
770 
771  ut_error;
772  }
773 
774  dfield = que_node_get_val(func_node);
775 
776  dfield_set_data(dfield, str1 + (4 - len1), len1);
777 }
778 
779 /*****************************************************************/
781 UNIV_INLINE
782 void
784 /*============*/
785  func_node_t* func_node)
786 {
787  que_node_t* arg1;
788  lint int_val;
789  byte* data;
790  int func;
791 
792  func = func_node->func;
793 
794  arg1 = func_node->args;
795 
796  if (func == PARS_LENGTH_TOKEN) {
797 
798  int_val = (lint) dfield_get_len(que_node_get_val(arg1));
799 
800  } else if (func == PARS_TO_CHAR_TOKEN) {
801 
802  /* Convert number to character string as a
803  signed decimal integer. */
804 
805  ulint uint_val;
806  int int_len;
807 
808  int_val = eval_node_get_int_val(arg1);
809 
810  /* Determine the length of the string. */
811 
812  if (int_val == 0) {
813  int_len = 1; /* the number 0 occupies 1 byte */
814  } else {
815  int_len = 0;
816  if (int_val < 0) {
817  uint_val = ((ulint) -int_val - 1) + 1;
818  int_len++; /* reserve space for minus sign */
819  } else {
820  uint_val = (ulint) int_val;
821  }
822  for (; uint_val > 0; int_len++) {
823  uint_val /= 10;
824  }
825  }
826 
827  /* allocate the string */
828  data = eval_node_ensure_val_buf(func_node, int_len + 1);
829 
830  /* add terminating NUL character */
831  data[int_len] = 0;
832 
833  /* convert the number */
834 
835  if (int_val == 0) {
836  data[0] = '0';
837  } else {
838  int tmp;
839  if (int_val < 0) {
840  data[0] = '-'; /* preceding minus sign */
841  uint_val = ((ulint) -int_val - 1) + 1;
842  } else {
843  uint_val = (ulint) int_val;
844  }
845  for (tmp = int_len; uint_val > 0; uint_val /= 10) {
846  data[--tmp] = (byte)
847  ('0' + (byte)(uint_val % 10));
848  }
849  }
850 
851  dfield_set_len(que_node_get_val(func_node), int_len);
852 
853  return;
854 
855  } else if (func == PARS_TO_NUMBER_TOKEN) {
856 
857  int_val = atoi((char*)
858  dfield_get_data(que_node_get_val(arg1)));
859 
860  } else if (func == PARS_SYSDATE_TOKEN) {
861  int_val = (lint) ut_time();
862  } else {
863  eval_predefined_2(func_node);
864 
865  return;
866  }
867 
868  eval_node_set_int_val(func_node, int_val);
869 }
870 
871 /*****************************************************************/
873 UNIV_INTERN
874 void
876 /*======*/
877  func_node_t* func_node)
878 {
879  que_node_t* arg;
880  ulint fclass;
881  ulint func;
882 
883  ut_ad(que_node_get_type(func_node) == QUE_NODE_FUNC);
884 
885  fclass = func_node->fclass;
886  func = func_node->func;
887 
888  arg = func_node->args;
889 
890  /* Evaluate first the argument list */
891  while (arg) {
892  eval_exp(arg);
893 
894  /* The functions are not defined for SQL null argument
895  values, except for eval_cmp and notfound */
896 
898  && (fclass != PARS_FUNC_CMP)
899  && (func != PARS_NOTFOUND_TOKEN)
900  && (func != PARS_PRINTF_TOKEN)) {
901  ut_error;
902  }
903 
904  arg = que_node_get_next(arg);
905  }
906 
907  switch (fclass) {
908  case PARS_FUNC_CMP:
909  eval_cmp(func_node);
910  return;
911  case PARS_FUNC_ARITH:
912  eval_arith(func_node);
913  return;
914  case PARS_FUNC_AGGREGATE:
915  eval_aggregate(func_node);
916  return;
918  switch (func) {
919  case PARS_NOTFOUND_TOKEN:
920  eval_notfound(func_node);
921  return;
922  case PARS_SUBSTR_TOKEN:
923  eval_substr(func_node);
924  return;
925  case PARS_REPLSTR_TOKEN:
926  eval_replstr(func_node);
927  return;
928  case PARS_INSTR_TOKEN:
929  eval_instr(func_node);
930  return;
931  case PARS_BINARY_TO_NUMBER_TOKEN:
932  eval_binary_to_number(func_node);
933  return;
934  case PARS_CONCAT_TOKEN:
935  eval_concat(func_node);
936  return;
937  case PARS_TO_BINARY_TOKEN:
938  eval_to_binary(func_node);
939  return;
940  default:
941  eval_predefined(func_node);
942  return;
943  }
944  case PARS_FUNC_LOGICAL:
945  eval_logical(func_node);
946  return;
947  }
948 
949  ut_error;
950 }