00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00027 #include "eval0eval.h"
00028
00029 #ifdef UNIV_NONINL
00030 #include "eval0eval.ic"
00031 #endif
00032
00033 #include "data0data.h"
00034 #include "row0sel.h"
00035
00037 static ulint eval_rnd = 128367121;
00038
00042 static byte eval_dummy;
00043
00044
00051 UNIV_INTERN
00052 byte*
00053 eval_node_alloc_val_buf(
00054
00055 que_node_t* node,
00058 ulint size)
00059 {
00060 dfield_t* dfield;
00061 byte* data;
00062
00063 ut_ad(que_node_get_type(node) == QUE_NODE_SYMBOL
00064 || que_node_get_type(node) == QUE_NODE_FUNC);
00065
00066 dfield = que_node_get_val(node);
00067
00068 data = static_cast<unsigned char *>(dfield_get_data(dfield));
00069
00070 if (data && data != &eval_dummy) {
00071 mem_free(data);
00072 }
00073
00074 if (size == 0) {
00075 data = &eval_dummy;
00076 } else {
00077 data = static_cast<unsigned char *>(mem_alloc(size));
00078 }
00079
00080 que_node_set_val_buf_size(node, size);
00081
00082 dfield_set_data(dfield, data, size);
00083
00084 return(data);
00085 }
00086
00087
00091 UNIV_INTERN
00092 void
00093 eval_node_free_val_buf(
00094
00095 que_node_t* node)
00096 {
00097 dfield_t* dfield;
00098 byte* data;
00099
00100 ut_ad(que_node_get_type(node) == QUE_NODE_SYMBOL
00101 || que_node_get_type(node) == QUE_NODE_FUNC);
00102
00103 dfield = que_node_get_val(node);
00104
00105 data = static_cast<unsigned char *>(dfield_get_data(dfield));
00106
00107 if (que_node_get_val_buf_size(node) > 0) {
00108 ut_a(data);
00109
00110 mem_free(data);
00111 }
00112 }
00113
00114
00117 UNIV_INTERN
00118 ibool
00119 eval_cmp(
00120
00121 func_node_t* cmp_node)
00122 {
00123 que_node_t* arg1;
00124 que_node_t* arg2;
00125 int res;
00126 ibool val;
00127 int func;
00128
00129 ut_ad(que_node_get_type(cmp_node) == QUE_NODE_FUNC);
00130
00131 arg1 = cmp_node->args;
00132 arg2 = que_node_get_next(arg1);
00133
00134 res = cmp_dfield_dfield(que_node_get_val(arg1),
00135 que_node_get_val(arg2));
00136 val = TRUE;
00137
00138 func = cmp_node->func;
00139
00140 if (func == '=') {
00141 if (res != 0) {
00142 val = FALSE;
00143 }
00144 } else if (func == '<') {
00145 if (res != -1) {
00146 val = FALSE;
00147 }
00148 } else if (func == PARS_LE_TOKEN) {
00149 if (res == 1) {
00150 val = FALSE;
00151 }
00152 } else if (func == PARS_NE_TOKEN) {
00153 if (res == 0) {
00154 val = FALSE;
00155 }
00156 } else if (func == PARS_GE_TOKEN) {
00157 if (res == -1) {
00158 val = FALSE;
00159 }
00160 } else {
00161 ut_ad(func == '>');
00162
00163 if (res != 1) {
00164 val = FALSE;
00165 }
00166 }
00167
00168 eval_node_set_ibool_val(cmp_node, val);
00169
00170 return(val);
00171 }
00172
00173
00175 UNIV_INLINE
00176 void
00177 eval_logical(
00178
00179 func_node_t* logical_node)
00180 {
00181 que_node_t* arg1;
00182 que_node_t* arg2;
00183 ibool val1;
00184 ibool val2 = 0;
00185 ibool val = 0;
00186 int func;
00187
00188 ut_ad(que_node_get_type(logical_node) == QUE_NODE_FUNC);
00189
00190 arg1 = logical_node->args;
00191 arg2 = que_node_get_next(arg1);
00192
00193 val1 = eval_node_get_ibool_val(arg1);
00194
00195 if (arg2) {
00196 val2 = eval_node_get_ibool_val(arg2);
00197 }
00198
00199 func = logical_node->func;
00200
00201 if (func == PARS_AND_TOKEN) {
00202 val = val1 & val2;
00203 } else if (func == PARS_OR_TOKEN) {
00204 val = val1 | val2;
00205 } else if (func == PARS_NOT_TOKEN) {
00206 val = TRUE - val1;
00207 } else {
00208 ut_error;
00209 }
00210
00211 eval_node_set_ibool_val(logical_node, val);
00212 }
00213
00214
00216 UNIV_INLINE
00217 void
00218 eval_arith(
00219
00220 func_node_t* arith_node)
00221 {
00222 que_node_t* arg1;
00223 que_node_t* arg2;
00224 lint val1;
00225 lint val2 = 0;
00226 lint val;
00227 int func;
00228
00229 ut_ad(que_node_get_type(arith_node) == QUE_NODE_FUNC);
00230
00231 arg1 = arith_node->args;
00232 arg2 = que_node_get_next(arg1);
00233
00234 val1 = eval_node_get_int_val(arg1);
00235
00236 if (arg2) {
00237 val2 = eval_node_get_int_val(arg2);
00238 }
00239
00240 func = arith_node->func;
00241
00242 if (func == '+') {
00243 val = val1 + val2;
00244 } else if ((func == '-') && arg2) {
00245 val = val1 - val2;
00246 } else if (func == '-') {
00247 val = -val1;
00248 } else if (func == '*') {
00249 val = val1 * val2;
00250 } else {
00251 ut_ad(func == '/');
00252 val = val1 / val2;
00253 }
00254
00255 eval_node_set_int_val(arith_node, val);
00256 }
00257
00258
00260 UNIV_INLINE
00261 void
00262 eval_aggregate(
00263
00264 func_node_t* node)
00265 {
00266 que_node_t* arg;
00267 lint val;
00268 lint arg_val;
00269 int func;
00270
00271 ut_ad(que_node_get_type(node) == QUE_NODE_FUNC);
00272
00273 val = eval_node_get_int_val(node);
00274
00275 func = node->func;
00276
00277 if (func == PARS_COUNT_TOKEN) {
00278
00279 val = val + 1;
00280 } else {
00281 ut_ad(func == PARS_SUM_TOKEN);
00282
00283 arg = node->args;
00284 arg_val = eval_node_get_int_val(arg);
00285
00286 val = val + arg_val;
00287 }
00288
00289 eval_node_set_int_val(node, val);
00290 }
00291
00292
00295 static
00296 void
00297 eval_predefined_2(
00298
00299 func_node_t* func_node)
00300 {
00301 que_node_t* arg;
00302 que_node_t* arg1;
00303 que_node_t* arg2 = 0;
00304 lint int_val;
00305 byte* data;
00306 ulint len1;
00307 ulint len2;
00308 int func;
00309 ulint i;
00310
00311 ut_ad(que_node_get_type(func_node) == QUE_NODE_FUNC);
00312
00313 arg1 = func_node->args;
00314
00315 if (arg1) {
00316 arg2 = que_node_get_next(arg1);
00317 }
00318
00319 func = func_node->func;
00320
00321 if (func == PARS_PRINTF_TOKEN) {
00322
00323 arg = arg1;
00324
00325 while (arg) {
00326 dfield_print(que_node_get_val(arg));
00327
00328 arg = que_node_get_next(arg);
00329 }
00330
00331 putc('\n', stderr);
00332
00333 } else if (func == PARS_ASSERT_TOKEN) {
00334
00335 if (!eval_node_get_ibool_val(arg1)) {
00336 fputs("SQL assertion fails in a stored procedure!\n",
00337 stderr);
00338 }
00339
00340 ut_a(eval_node_get_ibool_val(arg1));
00341
00342
00343
00344
00345 } else if (func == PARS_RND_TOKEN) {
00346
00347 len1 = (ulint)eval_node_get_int_val(arg1);
00348 len2 = (ulint)eval_node_get_int_val(arg2);
00349
00350 ut_ad(len2 >= len1);
00351
00352 if (len2 > len1) {
00353 int_val = (lint) (len1
00354 + (eval_rnd % (len2 - len1 + 1)));
00355 } else {
00356 int_val = (lint) len1;
00357 }
00358
00359 eval_rnd = ut_rnd_gen_next_ulint(eval_rnd);
00360
00361 eval_node_set_int_val(func_node, int_val);
00362
00363 } else if (func == PARS_RND_STR_TOKEN) {
00364
00365 len1 = (ulint)eval_node_get_int_val(arg1);
00366
00367 data = eval_node_ensure_val_buf(func_node, len1);
00368
00369 for (i = 0; i < len1; i++) {
00370 data[i] = (byte)(97 + (eval_rnd % 3));
00371
00372 eval_rnd = ut_rnd_gen_next_ulint(eval_rnd);
00373 }
00374 } else {
00375 ut_error;
00376 }
00377 }
00378
00379
00381 UNIV_INLINE
00382 void
00383 eval_notfound(
00384
00385 func_node_t* func_node)
00386 {
00387 sym_node_t* cursor;
00388 sel_node_t* sel_node;
00389 ibool ibool_val;
00390
00391 ut_ad(func_node->func == PARS_NOTFOUND_TOKEN);
00392
00393 cursor = static_cast<sym_node_t *>(func_node->args);
00394
00395 ut_ad(que_node_get_type(cursor) == QUE_NODE_SYMBOL);
00396
00397 if (cursor->token_type == SYM_LIT) {
00398
00399 ut_ad(ut_memcmp(dfield_get_data(que_node_get_val(cursor)),
00400 "SQL", 3) == 0);
00401
00402 sel_node = cursor->sym_table->query_graph->last_sel_node;
00403 } else {
00404 sel_node = cursor->alias->cursor_def;
00405 }
00406
00407 if (sel_node->state == SEL_NODE_NO_MORE_ROWS) {
00408 ibool_val = TRUE;
00409 } else {
00410 ibool_val = FALSE;
00411 }
00412
00413 eval_node_set_ibool_val(func_node, ibool_val);
00414 }
00415
00416
00418 UNIV_INLINE
00419 void
00420 eval_substr(
00421
00422 func_node_t* func_node)
00423 {
00424 que_node_t* arg1;
00425 que_node_t* arg2;
00426 que_node_t* arg3;
00427 dfield_t* dfield;
00428 byte* str1;
00429 ulint len1;
00430 ulint len2;
00431
00432 arg1 = func_node->args;
00433 arg2 = que_node_get_next(arg1);
00434
00435 ut_ad(func_node->func == PARS_SUBSTR_TOKEN);
00436
00437 arg3 = que_node_get_next(arg2);
00438
00439 str1 = static_cast<unsigned char *>(dfield_get_data(que_node_get_val(arg1)));
00440
00441 len1 = (ulint)eval_node_get_int_val(arg2);
00442 len2 = (ulint)eval_node_get_int_val(arg3);
00443
00444 dfield = que_node_get_val(func_node);
00445
00446 dfield_set_data(dfield, str1 + len1, len2);
00447 }
00448
00449
00451 static
00452 void
00453 eval_replstr(
00454
00455 func_node_t* func_node)
00456 {
00457 que_node_t* arg1;
00458 que_node_t* arg2;
00459 que_node_t* arg3;
00460 que_node_t* arg4;
00461 byte* str1;
00462 byte* str2;
00463 ulint len1;
00464 ulint len2;
00465
00466 arg1 = func_node->args;
00467 arg2 = que_node_get_next(arg1);
00468
00469 ut_ad(que_node_get_type(arg1) == QUE_NODE_SYMBOL);
00470
00471 arg3 = que_node_get_next(arg2);
00472 arg4 = que_node_get_next(arg3);
00473
00474 str1 = static_cast<unsigned char *>(dfield_get_data(que_node_get_val(arg1)));
00475 str2 = static_cast<unsigned char *>(dfield_get_data(que_node_get_val(arg2)));
00476
00477 len1 = (ulint)eval_node_get_int_val(arg3);
00478 len2 = (ulint)eval_node_get_int_val(arg4);
00479
00480 if ((dfield_get_len(que_node_get_val(arg1)) < len1 + len2)
00481 || (dfield_get_len(que_node_get_val(arg2)) < len2)) {
00482
00483 ut_error;
00484 }
00485
00486 ut_memcpy(str1 + len1, str2, len2);
00487 }
00488
00489
00491 static
00492 void
00493 eval_instr(
00494
00495 func_node_t* func_node)
00496 {
00497 que_node_t* arg1;
00498 que_node_t* arg2;
00499 dfield_t* dfield1;
00500 dfield_t* dfield2;
00501 lint int_val;
00502 byte* str1;
00503 byte* str2;
00504 byte match_char;
00505 ulint len1;
00506 ulint len2;
00507 ulint i;
00508 ulint j;
00509
00510 arg1 = func_node->args;
00511 arg2 = que_node_get_next(arg1);
00512
00513 dfield1 = que_node_get_val(arg1);
00514 dfield2 = que_node_get_val(arg2);
00515
00516 str1 = static_cast<unsigned char *>(dfield_get_data(dfield1));
00517 str2 = static_cast<unsigned char *>(dfield_get_data(dfield2));
00518
00519 len1 = dfield_get_len(dfield1);
00520 len2 = dfield_get_len(dfield2);
00521
00522 if (len2 == 0) {
00523 ut_error;
00524 }
00525
00526 match_char = str2[0];
00527
00528 for (i = 0; i < len1; i++) {
00529
00530
00531 if (str1[i] == match_char) {
00532
00533 if (i + len2 > len1) {
00534
00535 break;
00536 }
00537
00538 for (j = 1;; j++) {
00539
00540
00541 if (j == len2) {
00542 int_val = i + 1;
00543
00544 goto match_found;
00545 }
00546
00547 if (str1[i + j] != str2[j]) {
00548
00549 break;
00550 }
00551 }
00552 }
00553 }
00554
00555 int_val = 0;
00556
00557 match_found:
00558 eval_node_set_int_val(func_node, int_val);
00559 }
00560
00561
00563 UNIV_INLINE
00564 void
00565 eval_binary_to_number(
00566
00567 func_node_t* func_node)
00568 {
00569 que_node_t* arg1;
00570 dfield_t* dfield;
00571 byte* str1;
00572 byte* str2;
00573 ulint len1;
00574 ulint int_val;
00575
00576 arg1 = func_node->args;
00577
00578 dfield = que_node_get_val(arg1);
00579
00580 str1 = static_cast<unsigned char *>(dfield_get_data(dfield));
00581 len1 = dfield_get_len(dfield);
00582
00583 if (len1 > 4) {
00584 ut_error;
00585 }
00586
00587 if (len1 == 4) {
00588 str2 = str1;
00589 } else {
00590 int_val = 0;
00591 str2 = (byte*)&int_val;
00592
00593 ut_memcpy(str2 + (4 - len1), str1, len1);
00594 }
00595
00596 eval_node_copy_and_alloc_val(func_node, str2, 4);
00597 }
00598
00599
00601 static
00602 void
00603 eval_concat(
00604
00605 func_node_t* func_node)
00606 {
00607 que_node_t* arg;
00608 dfield_t* dfield;
00609 byte* data;
00610 ulint len;
00611 ulint len1;
00612
00613 arg = func_node->args;
00614 len = 0;
00615
00616 while (arg) {
00617 len1 = dfield_get_len(que_node_get_val(arg));
00618
00619 len += len1;
00620
00621 arg = que_node_get_next(arg);
00622 }
00623
00624 data = eval_node_ensure_val_buf(func_node, len);
00625
00626 arg = func_node->args;
00627 len = 0;
00628
00629 while (arg) {
00630 dfield = que_node_get_val(arg);
00631 len1 = dfield_get_len(dfield);
00632
00633 ut_memcpy(data + len, dfield_get_data(dfield), len1);
00634
00635 len += len1;
00636
00637 arg = que_node_get_next(arg);
00638 }
00639 }
00640
00641
00647 UNIV_INLINE
00648 void
00649 eval_to_binary(
00650
00651 func_node_t* func_node)
00652 {
00653 que_node_t* arg1;
00654 que_node_t* arg2;
00655 dfield_t* dfield;
00656 byte* str1;
00657 ulint len;
00658 ulint len1;
00659
00660 arg1 = func_node->args;
00661
00662 str1 = static_cast<unsigned char *>(dfield_get_data(que_node_get_val(arg1)));
00663
00664 if (dtype_get_mtype(que_node_get_data_type(arg1)) != DATA_INT) {
00665
00666 len = dfield_get_len(que_node_get_val(arg1));
00667
00668 dfield = que_node_get_val(func_node);
00669
00670 dfield_set_data(dfield, str1, len);
00671
00672 return;
00673 }
00674
00675 arg2 = que_node_get_next(arg1);
00676
00677 len1 = (ulint)eval_node_get_int_val(arg2);
00678
00679 if (len1 > 4) {
00680
00681 ut_error;
00682 }
00683
00684 dfield = que_node_get_val(func_node);
00685
00686 dfield_set_data(dfield, str1 + (4 - len1), len1);
00687 }
00688
00689
00691 UNIV_INLINE
00692 void
00693 eval_predefined(
00694
00695 func_node_t* func_node)
00696 {
00697 que_node_t* arg1;
00698 lint int_val;
00699 byte* data;
00700 int func;
00701
00702 func = func_node->func;
00703
00704 arg1 = func_node->args;
00705
00706 if (func == PARS_LENGTH_TOKEN) {
00707
00708 int_val = (lint)dfield_get_len(que_node_get_val(arg1));
00709
00710 } else if (func == PARS_TO_CHAR_TOKEN) {
00711
00712
00713
00714
00715 ulint uint_val;
00716 int int_len;
00717
00718 int_val = eval_node_get_int_val(arg1);
00719
00720
00721
00722 if (int_val == 0) {
00723 int_len = 1;
00724 } else {
00725 int_len = 0;
00726 if (int_val < 0) {
00727 uint_val = ((ulint) -int_val - 1) + 1;
00728 int_len++;
00729 } else {
00730 uint_val = (ulint) int_val;
00731 }
00732 for (; uint_val > 0; int_len++) {
00733 uint_val /= 10;
00734 }
00735 }
00736
00737
00738 data = eval_node_ensure_val_buf(func_node, int_len + 1);
00739
00740
00741 data[int_len] = 0;
00742
00743
00744
00745 if (int_val == 0) {
00746 data[0] = '0';
00747 } else {
00748 int tmp;
00749 if (int_val < 0) {
00750 data[0] = '-';
00751 uint_val = ((ulint) -int_val - 1) + 1;
00752 } else {
00753 uint_val = (ulint) int_val;
00754 }
00755 for (tmp = int_len; uint_val > 0; uint_val /= 10) {
00756 data[--tmp] = (byte)
00757 ('0' + (byte)(uint_val % 10));
00758 }
00759 }
00760
00761 dfield_set_len(que_node_get_val(func_node), int_len);
00762
00763 return;
00764
00765 } else if (func == PARS_TO_NUMBER_TOKEN) {
00766
00767 int_val = atoi((char*)
00768 dfield_get_data(que_node_get_val(arg1)));
00769
00770 } else if (func == PARS_SYSDATE_TOKEN) {
00771 int_val = (lint)ut_time();
00772 } else {
00773 eval_predefined_2(func_node);
00774
00775 return;
00776 }
00777
00778 eval_node_set_int_val(func_node, int_val);
00779 }
00780
00781
00783 UNIV_INTERN
00784 void
00785 eval_func(
00786
00787 func_node_t* func_node)
00788 {
00789 que_node_t* arg;
00790 ulint func_class;
00791 ulint func;
00792
00793 ut_ad(que_node_get_type(func_node) == QUE_NODE_FUNC);
00794
00795 func_class = func_node->func_class;
00796 func = func_node->func;
00797
00798 arg = func_node->args;
00799
00800
00801 while (arg) {
00802 eval_exp(arg);
00803
00804
00805
00806
00807 if (dfield_is_null(que_node_get_val(arg))
00808 && (func_class != PARS_FUNC_CMP)
00809 && (func != PARS_NOTFOUND_TOKEN)
00810 && (func != PARS_PRINTF_TOKEN)) {
00811 ut_error;
00812 }
00813
00814 arg = que_node_get_next(arg);
00815 }
00816
00817 if (func_class == PARS_FUNC_CMP) {
00818 eval_cmp(func_node);
00819 } else if (func_class == PARS_FUNC_ARITH) {
00820 eval_arith(func_node);
00821 } else if (func_class == PARS_FUNC_AGGREGATE) {
00822 eval_aggregate(func_node);
00823 } else if (func_class == PARS_FUNC_PREDEFINED) {
00824
00825 if (func == PARS_NOTFOUND_TOKEN) {
00826 eval_notfound(func_node);
00827 } else if (func == PARS_SUBSTR_TOKEN) {
00828 eval_substr(func_node);
00829 } else if (func == PARS_REPLSTR_TOKEN) {
00830 eval_replstr(func_node);
00831 } else if (func == PARS_INSTR_TOKEN) {
00832 eval_instr(func_node);
00833 } else if (func == PARS_BINARY_TO_NUMBER_TOKEN) {
00834 eval_binary_to_number(func_node);
00835 } else if (func == PARS_CONCAT_TOKEN) {
00836 eval_concat(func_node);
00837 } else if (func == PARS_TO_BINARY_TOKEN) {
00838 eval_to_binary(func_node);
00839 } else {
00840 eval_predefined(func_node);
00841 }
00842 } else {
00843 ut_ad(func_class == PARS_FUNC_LOGICAL);
00844
00845 eval_logical(func_node);
00846 }
00847 }