eval0eval.c
上传用户:tsgydb
上传日期:2007-04-14
资源大小:10674k
文件大小:15k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /******************************************************
  2. SQL evaluator: evaluates simple data structures, like expressions, in
  3. a query graph
  4. (c) 1997 Innobase Oy
  5. Created 12/29/1997 Heikki Tuuri
  6. *******************************************************/
  7. #include "eval0eval.h"
  8. #ifdef UNIV_NONINL
  9. #include "eval0eval.ic"
  10. #endif
  11. #include "data0data.h"
  12. #include "row0sel.h"
  13. /* The RND function seed */
  14. ulint eval_rnd  = 128367121;
  15. /* Dummy adress used when we should allocate a buffer of size 0 in
  16. the function below */
  17. byte eval_dummy;
  18. /*********************************************************************
  19. Allocate a buffer from global dynamic memory for a value of a que_node.
  20. NOTE that this memory must be explicitly freed when the query graph is
  21. freed. If the node already has an allocated buffer, that buffer is freed
  22. here. NOTE that this is the only function where dynamic memory should be
  23. allocated for a query node val field. */
  24. byte*
  25. eval_node_alloc_val_buf(
  26. /*====================*/
  27. /* out: pointer to allocated buffer */
  28. que_node_t* node, /* in: query graph node; sets the val field
  29. data field to point to the new buffer, and
  30. len field equal to size */
  31. ulint size) /* in: buffer size */
  32. {
  33. dfield_t* dfield;
  34. byte* data;
  35. ut_ad(que_node_get_type(node) == QUE_NODE_SYMBOL
  36.       || que_node_get_type(node) == QUE_NODE_FUNC);
  37. dfield = que_node_get_val(node);
  38. data = dfield_get_data(dfield);
  39. if (data && data != &eval_dummy) {
  40. mem_free(data);
  41. }
  42. if (size == 0) {
  43. data = &eval_dummy;
  44. } else {
  45. data = mem_alloc(size);
  46. }
  47. que_node_set_val_buf_size(node, size);
  48. dfield_set_data(dfield, data, size);
  49. return(data);
  50. }
  51. /*********************************************************************
  52. Free the buffer from global dynamic memory for a value of a que_node,
  53. if it has been allocated in the above function. The freeing for pushed
  54. column values is done in sel_col_prefetch_buf_free. */
  55. void
  56. eval_node_free_val_buf(
  57. /*===================*/
  58. que_node_t* node) /* in: query graph node */
  59. {
  60. dfield_t* dfield;
  61. byte* data;
  62. ut_ad(que_node_get_type(node) == QUE_NODE_SYMBOL
  63.       || que_node_get_type(node) == QUE_NODE_FUNC);
  64. dfield = que_node_get_val(node);
  65. data = dfield_get_data(dfield);
  66. if (que_node_get_val_buf_size(node) > 0) {
  67. ut_a(data);
  68. mem_free(data);
  69. }
  70. }
  71. /*********************************************************************
  72. Evaluates a comparison node. */
  73. ibool
  74. eval_cmp(
  75. /*=====*/
  76. /* out: the result of the comparison */
  77. func_node_t* cmp_node) /* in: comparison node */
  78. {
  79. que_node_t* arg1;
  80. que_node_t* arg2;
  81. int res;
  82. ibool val;
  83. int func;
  84. ut_ad(que_node_get_type(cmp_node) == QUE_NODE_FUNC);
  85. arg1 = cmp_node->args;
  86. arg2 = que_node_get_next(arg1);
  87. res = cmp_dfield_dfield(que_node_get_val(arg1),
  88. que_node_get_val(arg2));
  89. val = TRUE;
  90. func = cmp_node->func;
  91. if (func == '=') {
  92. if (res != 0) {
  93. val = FALSE;
  94. }
  95. } else if (func == '<') {
  96. if (res != -1) {
  97. val = FALSE;
  98. }
  99. } else if (func == PARS_LE_TOKEN) {
  100. if (res == 1) {
  101. val = FALSE;
  102. }
  103. } else if (func == PARS_NE_TOKEN) {
  104. if (res == 0) {
  105. val = FALSE;
  106. }
  107. } else if (func == PARS_GE_TOKEN) {
  108. if (res == -1) {
  109. val = FALSE;
  110. }
  111. } else {
  112. ut_ad(func == '>');
  113. if (res != 1) {
  114. val = FALSE;
  115. }
  116. }
  117. eval_node_set_ibool_val(cmp_node, val);
  118. return(val);
  119. }
  120. /*********************************************************************
  121. Evaluates a logical operation node. */
  122. UNIV_INLINE
  123. void
  124. eval_logical(
  125. /*=========*/
  126. func_node_t* logical_node) /* in: logical operation node */
  127. {
  128. que_node_t* arg1;
  129. que_node_t* arg2;
  130. ibool val1;
  131. ibool val2;
  132. ibool val;
  133. int func;
  134. ut_ad(que_node_get_type(logical_node) == QUE_NODE_FUNC);
  135. arg1 = logical_node->args;
  136. arg2 = que_node_get_next(arg1); /* arg2 is NULL if func is 'NOT' */
  137. val1 = eval_node_get_ibool_val(arg1);
  138. if (arg2) {
  139. val2 = eval_node_get_ibool_val(arg2);
  140. }
  141. func = logical_node->func;
  142. if (func == PARS_AND_TOKEN) {
  143. val = val1 & val2;
  144. } else if (func == PARS_OR_TOKEN) {
  145. val = val1 | val2;
  146. } else if (func == PARS_NOT_TOKEN) {
  147. val = TRUE - val1;
  148. } else {
  149. ut_error;
  150. }
  151. eval_node_set_ibool_val(logical_node, val);
  152. }
  153. /*********************************************************************
  154. Evaluates an arithmetic operation node. */
  155. UNIV_INLINE
  156. void
  157. eval_arith(
  158. /*=======*/
  159. func_node_t* arith_node) /* in: arithmetic operation node */
  160. {
  161. que_node_t* arg1;
  162. que_node_t* arg2;
  163. lint val1;
  164. lint val2;
  165. lint val;
  166. int func;
  167. ut_ad(que_node_get_type(arith_node) == QUE_NODE_FUNC);
  168. arg1 = arith_node->args;
  169. arg2 = que_node_get_next(arg1); /* arg2 is NULL if func is unary '-' */
  170. val1 = eval_node_get_int_val(arg1);
  171. if (arg2) {
  172. val2 = eval_node_get_int_val(arg2);
  173. }
  174. func = arith_node->func;
  175. if (func == '+') {
  176. val = val1 + val2;
  177. } else if ((func == '-') && arg2) {
  178. val = val1 - val2;
  179. } else if (func == '-') {
  180. val = -val1;
  181. } else if (func == '*') {
  182. val = val1 * val2;
  183. } else {
  184. ut_ad(func == '/');
  185. val = val1 / val2;
  186. }
  187. eval_node_set_int_val(arith_node, val);
  188. }
  189. /*********************************************************************
  190. Evaluates an aggregate operation node. */
  191. UNIV_INLINE
  192. void
  193. eval_aggregate(
  194. /*===========*/
  195. func_node_t* node) /* in: aggregate operation node */
  196. {
  197. que_node_t* arg;
  198. lint val;
  199. lint arg_val;
  200. int func;
  201. ut_ad(que_node_get_type(node) == QUE_NODE_FUNC);
  202. val = eval_node_get_int_val(node);
  203. func = node->func;
  204. if (func == PARS_COUNT_TOKEN) {
  205. val = val + 1;
  206. } else {
  207. ut_ad(func == PARS_SUM_TOKEN);
  208. arg = node->args;
  209. arg_val = eval_node_get_int_val(arg);
  210. val = val + arg_val;
  211. }
  212. eval_node_set_int_val(node, val);
  213. }
  214. /*********************************************************************
  215. Evaluates a predefined function node where the function is not relevant
  216. in benchmarks. */
  217. static
  218. void
  219. eval_predefined_2(
  220. /*==============*/
  221. func_node_t* func_node) /* in: predefined function node */
  222. {
  223. que_node_t* arg;
  224. que_node_t* arg1;
  225. que_node_t* arg2;
  226. lint int_val;
  227. byte* data;
  228. ulint len1;
  229. ulint len2;
  230. int func;
  231. ulint i;
  232. ut_ad(que_node_get_type(func_node) == QUE_NODE_FUNC);
  233. arg1 = func_node->args;
  234. if (arg1) {
  235. arg2 = que_node_get_next(arg1);
  236. }
  237. func = func_node->func;
  238. if (func == PARS_PRINTF_TOKEN) {
  239. arg = arg1;
  240. while (arg) {
  241. dfield_print(que_node_get_val(arg));
  242. arg = que_node_get_next(arg);
  243. }
  244. printf("n");
  245. } else if (func == PARS_ASSERT_TOKEN) {
  246. if (!eval_node_get_ibool_val(arg1)) {
  247. printf("SQL assertion fails in a stored procedure!n");
  248. }
  249.  
  250. ut_a(eval_node_get_ibool_val(arg1));
  251. /* This function, or more precisely, a debug procedure,
  252. returns no value */
  253. } else if (func == PARS_RND_TOKEN) {
  254. len1 = (ulint)eval_node_get_int_val(arg1);
  255. len2 = (ulint)eval_node_get_int_val(arg2);
  256. ut_ad(len2 >= len1);
  257. if (len2 > len1) {
  258. int_val = (lint)(len1 +
  259. (eval_rnd % (len2 - len1 + 1)));
  260. } else {
  261. int_val = (lint)len1;
  262. }
  263. eval_rnd = ut_rnd_gen_next_ulint(eval_rnd);
  264. eval_node_set_int_val(func_node, int_val);
  265. } else if (func == PARS_RND_STR_TOKEN) {
  266. len1 = (ulint)eval_node_get_int_val(arg1);
  267. data = eval_node_ensure_val_buf(func_node, len1);
  268. for (i = 0; i < len1; i++) {
  269. data[i] = (byte)(97 + (eval_rnd % 3));
  270. eval_rnd = ut_rnd_gen_next_ulint(eval_rnd);
  271. }
  272. } else {
  273. ut_error;
  274. }
  275. }
  276. /*********************************************************************
  277. Evaluates a notfound-function node. */
  278. UNIV_INLINE
  279. void
  280. eval_notfound(
  281. /*==========*/
  282. func_node_t* func_node) /* in: function node */
  283. {
  284. que_node_t* arg1;
  285. que_node_t* arg2;
  286. sym_node_t* cursor;
  287. sel_node_t* sel_node;
  288. ibool ibool_val;
  289. arg1 = func_node->args;
  290. arg2 = que_node_get_next(arg1);
  291. ut_ad(func_node->func == PARS_NOTFOUND_TOKEN);
  292. cursor = arg1;
  293. ut_ad(que_node_get_type(cursor) == QUE_NODE_SYMBOL);
  294. if (cursor->token_type == SYM_LIT) {
  295. ut_ad(ut_memcmp(dfield_get_data(que_node_get_val(cursor)),
  296. "SQL", 3) == 0);
  297. sel_node = cursor->sym_table->query_graph->last_sel_node;
  298. } else {
  299. sel_node = cursor->alias->cursor_def;
  300. }
  301. if (sel_node->state == SEL_NODE_NO_MORE_ROWS) {
  302. ibool_val = TRUE;
  303. } else {
  304. ibool_val = FALSE;
  305. }
  306. eval_node_set_ibool_val(func_node, ibool_val);
  307. }
  308. /*********************************************************************
  309. Evaluates a substr-function node. */
  310. UNIV_INLINE
  311. void
  312. eval_substr(
  313. /*========*/
  314. func_node_t* func_node) /* in: function node */
  315. {
  316. que_node_t* arg1;
  317. que_node_t* arg2;
  318. que_node_t* arg3;
  319. dfield_t* dfield;
  320. byte* str1;
  321. ulint len1;
  322. ulint len2;
  323. arg1 = func_node->args;
  324. arg2 = que_node_get_next(arg1);
  325. ut_ad(func_node->func == PARS_SUBSTR_TOKEN);
  326. arg3 = que_node_get_next(arg2);
  327. str1 = dfield_get_data(que_node_get_val(arg1));
  328. len1 = (ulint)eval_node_get_int_val(arg2);
  329. len2 = (ulint)eval_node_get_int_val(arg3);
  330. dfield = que_node_get_val(func_node);
  331. dfield_set_data(dfield, str1 + len1, len2);
  332. }
  333. /*********************************************************************
  334. Evaluates a replstr-procedure node. */
  335. static
  336. void
  337. eval_replstr(
  338. /*=========*/
  339. func_node_t* func_node) /* in: function node */
  340. {
  341. que_node_t* arg1;
  342. que_node_t* arg2;
  343. que_node_t* arg3;
  344. que_node_t* arg4;
  345. byte* str1;
  346. byte* str2;
  347. ulint len1;
  348. ulint len2;
  349. arg1 = func_node->args;
  350. arg2 = que_node_get_next(arg1);
  351. ut_ad(que_node_get_type(arg1) == QUE_NODE_SYMBOL);
  352. arg3 = que_node_get_next(arg2);
  353. arg4 = que_node_get_next(arg3);
  354. str1 = dfield_get_data(que_node_get_val(arg1));
  355. str2 = dfield_get_data(que_node_get_val(arg2));
  356. len1 = (ulint)eval_node_get_int_val(arg3);
  357. len2 = (ulint)eval_node_get_int_val(arg4);
  358. if ((dfield_get_len(que_node_get_val(arg1)) < len1 + len2)
  359. || (dfield_get_len(que_node_get_val(arg2)) < len2)) {
  360. ut_error;
  361. }
  362. ut_memcpy(str1 + len1, str2, len2);
  363. }
  364. /*********************************************************************
  365. Evaluates an instr-function node. */
  366. static
  367. void
  368. eval_instr(
  369. /*=======*/
  370. func_node_t* func_node) /* in: function node */
  371. {
  372. que_node_t* arg1;
  373. que_node_t* arg2;
  374. dfield_t* dfield1;
  375. dfield_t* dfield2;
  376. lint int_val;
  377. byte* str1;
  378. byte* str2;
  379. byte match_char;
  380. ulint len1;
  381. ulint len2;
  382. ulint i;
  383. ulint j;
  384. arg1 = func_node->args;
  385. arg2 = que_node_get_next(arg1);
  386. dfield1 = que_node_get_val(arg1);
  387. dfield2 = que_node_get_val(arg2);
  388. str1 = dfield_get_data(dfield1);
  389. str2 = dfield_get_data(dfield2);
  390. len1 = dfield_get_len(dfield1);
  391. len2 = dfield_get_len(dfield2);
  392. if (len2 == 0) {
  393. ut_error;
  394. }
  395. match_char = str2[0];
  396. for (i = 0; i < len1; i++) {
  397. /* In this outer loop, the number of matched characters is 0 */
  398. if (str1[i] == match_char) {
  399. if (i + len2 > len1) {
  400. break;
  401. }
  402. for (j = 1;; j++) {
  403. /* We have already matched j characters */
  404. if (j == len2) {
  405. int_val = i + 1;
  406. goto match_found;
  407. }
  408. if (str1[i + j] != str2[j]) {
  409. break;
  410. }
  411. }
  412. }
  413. }
  414. int_val = 0;
  415. match_found:
  416. eval_node_set_int_val(func_node, int_val);
  417. }
  418. /*********************************************************************
  419. Evaluates a predefined function node. */
  420. UNIV_INLINE
  421. void
  422. eval_binary_to_number(
  423. /*==================*/
  424. func_node_t* func_node) /* in: function node */
  425. {
  426. que_node_t* arg1;
  427. dfield_t* dfield;
  428. byte* str1;
  429. byte* str2;
  430. ulint len1;
  431. ulint int_val;
  432. arg1 = func_node->args;
  433. dfield = que_node_get_val(arg1);
  434. str1 = dfield_get_data(dfield);
  435. len1 = dfield_get_len(dfield);
  436.   if (len1 > 4) {
  437. ut_error;
  438. }
  439. if (len1 == 4) {
  440. str2 = str1;
  441. } else {
  442. int_val = 0;
  443. str2 = (byte*)&int_val;
  444. ut_memcpy(str2 + (4 - len1), str1, len1);
  445. }
  446. eval_node_copy_and_alloc_val(func_node, str2, 4);
  447. }
  448. /*********************************************************************
  449. Evaluates a predefined function node. */
  450. static
  451. void
  452. eval_concat(
  453. /*========*/
  454. func_node_t* func_node) /* in: function node */
  455. {
  456. que_node_t* arg;
  457. dfield_t* dfield;
  458. byte* data;
  459. ulint len;
  460. ulint len1;
  461. arg = func_node->args;
  462. len = 0;
  463. while (arg) {
  464. len1 = dfield_get_len(que_node_get_val(arg));
  465. len += len1;
  466. arg = que_node_get_next(arg);
  467. }
  468. data = eval_node_ensure_val_buf(func_node, len);
  469. arg = func_node->args;
  470. len = 0;
  471. while (arg) {
  472. dfield = que_node_get_val(arg);
  473. len1 = dfield_get_len(dfield);
  474. ut_memcpy(data + len, dfield_get_data(dfield), len1);
  475. len += len1;
  476. arg = que_node_get_next(arg);
  477. }
  478. }
  479. /*********************************************************************
  480. Evaluates a predefined function node. */
  481. UNIV_INLINE
  482. void
  483. eval_to_binary(
  484. /*===========*/
  485. func_node_t* func_node) /* in: function node */
  486. {
  487. que_node_t* arg1;
  488. que_node_t* arg2;
  489. dfield_t* dfield;
  490. byte* str1;
  491. ulint len1;
  492. arg1 = func_node->args;
  493. str1 = dfield_get_data(que_node_get_val(arg1));
  494. arg2 = que_node_get_next(arg1);
  495. len1 = (ulint)eval_node_get_int_val(arg2);
  496. if (len1 > 4) {
  497. ut_error;
  498. }
  499. dfield = que_node_get_val(func_node);
  500. dfield_set_data(dfield, str1 + (4 - len1), len1);
  501. }
  502. /*********************************************************************
  503. Evaluates a predefined function node. */
  504. UNIV_INLINE
  505. void
  506. eval_predefined(
  507. /*============*/
  508. func_node_t* func_node) /* in: function node */
  509. {
  510. que_node_t* arg1;
  511. lint int_val;
  512. byte* str1;
  513. byte* data;
  514. int func;
  515. func = func_node->func;
  516. arg1 = func_node->args;
  517. if (func == PARS_LENGTH_TOKEN) {
  518. int_val = (lint)dfield_get_len(que_node_get_val(arg1));
  519. } else if (func == PARS_TO_CHAR_TOKEN) {
  520. int_val = eval_node_get_int_val(arg1);
  521. data = eval_node_ensure_val_buf(func_node, 11);
  522. sprintf((char*)data, "%10li", int_val);
  523. dfield_set_len(que_node_get_val(func_node), 10);
  524. return;
  525. } else if (func == PARS_TO_NUMBER_TOKEN) {
  526. str1 = dfield_get_data(que_node_get_val(arg1));
  527. int_val = atoi((char*)str1);
  528. } else if (func == PARS_SYSDATE_TOKEN) {
  529. int_val = (lint)ut_time();
  530. } else {
  531. eval_predefined_2(func_node);
  532. return;
  533. }
  534. eval_node_set_int_val(func_node, int_val); 
  535. }
  536. /*********************************************************************
  537. Evaluates a function node. */
  538. void
  539. eval_func(
  540. /*======*/
  541. func_node_t* func_node) /* in: function node */
  542. {
  543. que_node_t* arg;
  544. ulint class;
  545. ulint func;
  546. ut_ad(que_node_get_type(func_node) == QUE_NODE_FUNC);
  547. class = func_node->class;
  548. func = func_node->func;
  549. arg = func_node->args;
  550. /* Evaluate first the argument list */
  551. while (arg) {
  552. eval_exp(arg);
  553. /* The functions are not defined for SQL null argument
  554. values, except for eval_cmp and notfound */
  555. if ((dfield_get_len(que_node_get_val(arg)) == UNIV_SQL_NULL)
  556. && (class != PARS_FUNC_CMP)
  557. && (func != PARS_NOTFOUND_TOKEN)
  558. && (func != PARS_PRINTF_TOKEN)) {
  559. ut_error;
  560. }
  561. arg = que_node_get_next(arg);
  562. }
  563. if (class == PARS_FUNC_CMP) {
  564. eval_cmp(func_node);
  565. } else if (class == PARS_FUNC_ARITH) {
  566. eval_arith(func_node);
  567. } else if (class == PARS_FUNC_AGGREGATE) {
  568. eval_aggregate(func_node);
  569. } else if (class == PARS_FUNC_PREDEFINED) {
  570. if (func == PARS_NOTFOUND_TOKEN) {
  571. eval_notfound(func_node);
  572. } else if (func == PARS_SUBSTR_TOKEN) {
  573. eval_substr(func_node);
  574. } else if (func == PARS_REPLSTR_TOKEN) {
  575. eval_replstr(func_node);
  576. } else if (func == PARS_INSTR_TOKEN) {
  577. eval_instr(func_node);
  578. } else if (func == PARS_BINARY_TO_NUMBER_TOKEN) {
  579. eval_binary_to_number(func_node);
  580. } else if (func == PARS_CONCAT_TOKEN) {
  581. eval_concat(func_node);
  582. } else if (func == PARS_TO_BINARY_TOKEN) {
  583. eval_to_binary(func_node);
  584. } else {
  585. eval_predefined(func_node);
  586. }
  587. } else {
  588. ut_ad(class == PARS_FUNC_LOGICAL);
  589. eval_logical(func_node);
  590. }
  591. }