Drizzled Public API Documentation

eval0eval.cc
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
14 this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
15 St, Fifth Floor, Boston, MA 02110-1301 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 
37 static ulint eval_rnd = 128367121;
38 
42 static byte eval_dummy;
43 
44 /*****************************************************************/
51 UNIV_INTERN
52 byte*
53 eval_node_alloc_val_buf(
54 /*====================*/
55  que_node_t* node,
58  ulint size)
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 = static_cast<unsigned char *>(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 = static_cast<unsigned char *>(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 
87 /*****************************************************************/
91 UNIV_INTERN
92 void
93 eval_node_free_val_buf(
94 /*===================*/
95  que_node_t* node)
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 = static_cast<unsigned char *>(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 
114 /*****************************************************************/
117 UNIV_INTERN
118 ibool
119 eval_cmp(
120 /*=====*/
121  func_node_t* cmp_node)
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 
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 
173 /*****************************************************************/
175 UNIV_INLINE
176 void
177 eval_logical(
178 /*=========*/
179  func_node_t* logical_node)
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 
214 /*****************************************************************/
216 UNIV_INLINE
217 void
218 eval_arith(
219 /*=======*/
220  func_node_t* arith_node)
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 
258 /*****************************************************************/
260 UNIV_INLINE
261 void
262 eval_aggregate(
263 /*===========*/
264  func_node_t* node)
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 
292 /*****************************************************************/
295 static
296 void
297 eval_predefined_2(
298 /*==============*/
299  func_node_t* func_node)
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 
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 
379 /*****************************************************************/
381 UNIV_INLINE
382 void
383 eval_notfound(
384 /*==========*/
385  func_node_t* func_node)
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 
393  cursor = static_cast<sym_node_t *>(func_node->args);
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 
416 /*****************************************************************/
418 UNIV_INLINE
419 void
420 eval_substr(
421 /*========*/
422  func_node_t* func_node)
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 = static_cast<unsigned char *>(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 
449 /*****************************************************************/
451 static
452 void
453 eval_replstr(
454 /*=========*/
455  func_node_t* func_node)
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 = 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)));
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 
489 /*****************************************************************/
491 static
492 void
493 eval_instr(
494 /*=======*/
495  func_node_t* func_node)
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 = static_cast<unsigned char *>(dfield_get_data(dfield1));
517  str2 = static_cast<unsigned char *>(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 
561 /*****************************************************************/
563 UNIV_INLINE
564 void
565 eval_binary_to_number(
566 /*==================*/
567  func_node_t* func_node)
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 = static_cast<unsigned char *>(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 
599 /*****************************************************************/
601 static
602 void
603 eval_concat(
604 /*========*/
605  func_node_t* func_node)
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 /*****************************************************************/
647 UNIV_INLINE
648 void
649 eval_to_binary(
650 /*===========*/
651  func_node_t* func_node)
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 = static_cast<unsigned char *>(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 
689 /*****************************************************************/
691 UNIV_INLINE
692 void
693 eval_predefined(
694 /*============*/
695  func_node_t* func_node)
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 
781 /*****************************************************************/
783 UNIV_INTERN
784 void
785 eval_func(
786 /*======*/
787  func_node_t* func_node)
788 {
789  que_node_t* arg;
790  ulint func_class;
791  ulint func;
792 
793  ut_ad(que_node_get_type(func_node) == QUE_NODE_FUNC);
794 
795  func_class = func_node->func_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 
808  && (func_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 (func_class == PARS_FUNC_CMP) {
818  eval_cmp(func_node);
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) {
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(func_class == PARS_FUNC_LOGICAL);
844 
845  eval_logical(func_node);
846  }
847 }