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

MySQL数据库

开发平台:

Visual C++

  1. /************************************************************************
  2. SQL data field and tuple
  3. (c) 1994-1996 Innobase Oy
  4. Created 5/30/1994 Heikki Tuuri
  5. *************************************************************************/
  6. #include "data0data.h"
  7. #ifdef UNIV_NONINL
  8. #include "data0data.ic"
  9. #endif
  10. #include "ut0rnd.h"
  11. byte data_error; /* data pointers of tuple fields are initialized
  12. to point here for error checking */
  13. ulint data_dummy; /* this is used to fool the compiler in
  14. dtuple_validate */
  15. byte data_buf[8192]; /* used in generating test tuples */
  16. ulint data_rnd = 756511;
  17. /* Some non-inlined functions used in the MySQL interface: */
  18. void 
  19. dfield_set_data_noninline(
  20. dfield_t*  field, /* in: field */
  21. void* data, /* in: data */
  22. ulint len) /* in: length or UNIV_SQL_NULL */
  23. {
  24. dfield_set_data(field, data, len);
  25. }
  26. void* 
  27. dfield_get_data_noninline(
  28. dfield_t* field) /* in: field */
  29. {
  30. return(dfield_get_data(field));
  31. }
  32. ulint
  33. dfield_get_len_noninline(
  34. dfield_t* field) /* in: field */
  35. {
  36. return(dfield_get_len(field));
  37. }
  38. ulint 
  39. dtuple_get_n_fields_noninline(
  40. dtuple_t*  tuple) /* in: tuple */
  41. {
  42. return(dtuple_get_n_fields(tuple));
  43. }
  44. dfield_t* 
  45. dtuple_get_nth_field_noninline(
  46. dtuple_t*  tuple, /* in: tuple */
  47. ulint n) /* in: index of field */
  48. {
  49. return(dtuple_get_nth_field(tuple, n));
  50. }
  51. /*************************************************************************
  52. Creates a dtuple for use in MySQL. */
  53. dtuple_t*
  54. dtuple_create_for_mysql(
  55. /*====================*/
  56. /* out, own created dtuple */
  57. void**  heap,     /* out: created memory heap */
  58. ulint  n_fields)  /* in: number of fields */
  59. {
  60.    *heap = (void*)mem_heap_create(500);
  61.  
  62.    return(dtuple_create(*((mem_heap_t**)heap), n_fields));  
  63. }
  64. /*************************************************************************
  65. Frees a dtuple used in MySQL. */
  66. void
  67. dtuple_free_for_mysql(
  68. /*==================*/
  69. void* heap) /* in: memory heap where tuple was created */
  70. {
  71.    mem_heap_free((mem_heap_t*)heap);
  72. }
  73. /*************************************************************************
  74. Sets number of fields used in a tuple. Normally this is set in
  75. dtuple_create, but if you want later to set it smaller, you can use this. */ 
  76. void
  77. dtuple_set_n_fields(
  78. /*================*/
  79. dtuple_t* tuple, /* in: tuple */
  80. ulint n_fields) /* in: number of fields */
  81. {
  82. ut_ad(tuple);
  83. tuple->n_fields = n_fields;
  84. tuple->n_fields_cmp = n_fields;
  85. }
  86. /**************************************************************
  87. Checks that a data field is typed. Asserts an error if not. */
  88. ibool
  89. dfield_check_typed(
  90. /*===============*/
  91. /* out: TRUE if ok */
  92. dfield_t* field) /* in: data field */
  93. {
  94. ut_a(dfield_get_type(field)->mtype <= DATA_SYS);
  95. ut_a(dfield_get_type(field)->mtype >= DATA_VARCHAR);
  96. return(TRUE);
  97. }
  98. /**************************************************************
  99. Checks that a data tuple is typed. Asserts an error if not. */
  100. ibool
  101. dtuple_check_typed(
  102. /*===============*/
  103. /* out: TRUE if ok */
  104. dtuple_t* tuple) /* in: tuple */
  105. {
  106. dfield_t* field;
  107. ulint   i;
  108. for (i = 0; i < dtuple_get_n_fields(tuple); i++) {
  109. field = dtuple_get_nth_field(tuple, i);
  110. ut_a(dfield_check_typed(field));
  111. }
  112. return(TRUE);
  113. }
  114. /**************************************************************
  115. Validates the consistency of a tuple which must be complete, i.e,
  116. all fields must have been set. */
  117. ibool
  118. dtuple_validate(
  119. /*============*/
  120. /* out: TRUE if ok */
  121. dtuple_t* tuple) /* in: tuple */
  122. {
  123. dfield_t* field;
  124. byte*   data;
  125. ulint   n_fields;
  126. ulint   len;
  127. ulint   i;
  128. ulint   j;
  129. ut_a(tuple->magic_n = DATA_TUPLE_MAGIC_N);
  130. n_fields = dtuple_get_n_fields(tuple);
  131. /* We dereference all the data of each field to test
  132. for memory traps */
  133. for (i = 0; i < n_fields; i++) {
  134. field = dtuple_get_nth_field(tuple, i);
  135. len = dfield_get_len(field);
  136. if (len != UNIV_SQL_NULL) {
  137. data = field->data;
  138. for (j = 0; j < len; j++) {
  139. data_dummy  += *data; /* fool the compiler not
  140. to optimize out this
  141. code */
  142. data++;
  143. }
  144. }
  145. }
  146. ut_a(dtuple_check_typed(tuple));
  147. return(TRUE);
  148. }
  149. /*****************************************************************
  150. Pretty prints a dfield value according to its data type. */
  151. void
  152. dfield_print(
  153. /*=========*/
  154. dfield_t* dfield)  /* in: dfield */
  155. {
  156. byte* data;
  157. ulint len;
  158. ulint mtype;
  159. ulint i;
  160. len = dfield_get_len(dfield);
  161. data = dfield_get_data(dfield);
  162. if (len == UNIV_SQL_NULL) {
  163. printf("NULL");
  164. return;
  165. }
  166. mtype = dtype_get_mtype(dfield_get_type(dfield));
  167. if ((mtype == DATA_CHAR) || (mtype == DATA_VARCHAR)) {
  168. for (i = 0; i < len; i++) {
  169. if (isprint((char)(*data))) {
  170. printf("%c", (char)*data);
  171. } else {
  172. printf(" ");
  173. }
  174. data++;
  175. }
  176. } else if (mtype == DATA_INT) {
  177. ut_a(len == 4); /* only works for 32-bit integers */
  178. printf("%i", (int)mach_read_from_4(data));
  179. } else {
  180. ut_error;
  181. }
  182. }
  183. /*****************************************************************
  184. Pretty prints a dfield value according to its data type. Also the hex string
  185. is printed if a string contains non-printable characters. */ 
  186. void
  187. dfield_print_also_hex(
  188. /*==================*/
  189. dfield_t* dfield)  /* in: dfield */
  190. {
  191. byte* data;
  192. ulint len;
  193. ulint mtype;
  194. ulint i;
  195. ibool print_also_hex;
  196. len = dfield_get_len(dfield);
  197. data = dfield_get_data(dfield);
  198. if (len == UNIV_SQL_NULL) {
  199. printf("NULL");
  200. return;
  201. }
  202. mtype = dtype_get_mtype(dfield_get_type(dfield));
  203. if ((mtype == DATA_CHAR) || (mtype == DATA_VARCHAR)) {
  204. print_also_hex = FALSE;
  205. for (i = 0; i < len; i++) {
  206. if (isprint((char)(*data))) {
  207. printf("%c", (char)*data);
  208. } else {
  209. print_also_hex = TRUE;
  210. printf(" ");
  211. }
  212. data++;
  213. }
  214. if (!print_also_hex) {
  215. return;
  216. }
  217. printf(" Hex: ");
  218. data = dfield_get_data(dfield);
  219. for (i = 0; i < len; i++) {
  220. printf("%02lx", (ulint)*data);
  221. data++;
  222. }
  223. } else if (mtype == DATA_INT) {
  224. ut_a(len == 4); /* inly works for 32-bit integers */
  225. printf("%i", (int)mach_read_from_4(data));
  226. } else {
  227. ut_error;
  228. }
  229. }
  230. /**************************************************************
  231. The following function prints the contents of a tuple. */
  232. void
  233. dtuple_print(
  234. /*=========*/
  235. dtuple_t* tuple) /* in: tuple */
  236. {
  237. dfield_t* field;
  238. ulint n_fields;
  239. ulint i;
  240. n_fields = dtuple_get_n_fields(tuple);
  241. printf("DATA TUPLE: %lu fields;n", n_fields);
  242. for (i = 0; i < n_fields; i++) {
  243. printf(" %lu:", i);
  244. field = dtuple_get_nth_field(tuple, i);
  245. if (field->len != UNIV_SQL_NULL) {
  246. ut_print_buf(field->data, field->len);
  247. } else {
  248. printf(" SQL NULL");
  249. }
  250. printf(";");
  251. }
  252. printf("n");
  253. dtuple_validate(tuple);
  254. }
  255. /**************************************************************
  256. The following function prints the contents of a tuple to a buffer. */
  257. ulint
  258. dtuple_sprintf(
  259. /*===========*/
  260. /* out: printed length in bytes */
  261. char* buf, /* in: print buffer */
  262. ulint buf_len,/* in: buf length in bytes */
  263. dtuple_t* tuple) /* in: tuple */
  264. {
  265. dfield_t* field;
  266. ulint n_fields;
  267. ulint len;
  268. ulint i;
  269. len = 0;
  270. n_fields = dtuple_get_n_fields(tuple);
  271. for (i = 0; i < n_fields; i++) {
  272. if (len + 30 > buf_len) {
  273. return(len);
  274. }
  275. len += sprintf(buf + len, " %lu:", i);
  276. field = dtuple_get_nth_field(tuple, i);
  277. if (field->len != UNIV_SQL_NULL) {
  278. if (5 * field->len + len + 30 > buf_len) {
  279. return(len);
  280. }
  281. len += ut_sprintf_buf(buf + len, field->data,
  282. field->len);
  283. } else {
  284. len += sprintf(buf + len, " SQL NULL");
  285. }
  286. len += sprintf(buf + len, ";");
  287. }
  288. return(len);
  289. }
  290. #ifdef notdefined
  291. /******************************************************************
  292. Generates random numbers, where 10/16 is uniformly
  293. distributed between 0 and n1, 5/16 between 0 and n2,
  294. and 1/16 between 0 and n3. */
  295. static
  296. ulint
  297. dtuple_gen_rnd_ulint(
  298. /*=================*/
  299. /* out: random ulint */
  300. ulint n1,
  301. ulint n2,
  302. ulint n3)
  303. {
  304. ulint  m;
  305. ulint n;
  306. m = ut_rnd_gen_ulint() % 16;
  307. if (m < 10) {
  308. n = n1;
  309. } else if (m < 15) {
  310. n = n2;
  311. } else {
  312. n = n3;
  313. }
  314. m = ut_rnd_gen_ulint();
  315. return(m % n);
  316. }
  317. /***************************************************************
  318. Generates a random tuple. */
  319. dtuple_t*
  320. dtuple_gen_rnd_tuple(
  321. /*=================*/
  322. /* out: pointer to the tuple */
  323. mem_heap_t* heap) /* in: memory heap where generated */
  324. {
  325. ulint n_fields;
  326. dfield_t* field;
  327. ulint len;
  328. dtuple_t* tuple;
  329. ulint i;
  330. ulint j;
  331. byte* ptr;
  332. n_fields = dtuple_gen_rnd_ulint(5, 30, 300) + 1;
  333. tuple = dtuple_create(heap, n_fields);
  334. for (i = 0; i < n_fields; i++) {
  335. if (n_fields < 7) {
  336. len = dtuple_gen_rnd_ulint(5, 30, 400);
  337. } else {
  338. len = dtuple_gen_rnd_ulint(7, 5, 17);
  339. }
  340. field = dtuple_get_nth_field(tuple, i);
  341. if (len == 0) {
  342. dfield_set_data(field, NULL, UNIV_SQL_NULL);
  343. } else {
  344. ptr = mem_heap_alloc(heap, len);
  345. dfield_set_data(field, ptr, len - 1);
  346. for (j = 0; j < len; j++) {
  347. *ptr = (byte)(65 + 
  348. dtuple_gen_rnd_ulint(22, 22, 22));
  349. ptr++;
  350. }
  351. }
  352. dtype_set(dfield_get_type(field), DATA_VARCHAR,
  353. DATA_ENGLISH, 500, 0);
  354. }
  355. ut_a(dtuple_validate(tuple));
  356. return(tuple);
  357. }
  358. /*******************************************************************
  359. Generates a test tuple for sort and comparison tests. */
  360. void
  361. dtuple_gen_test_tuple(
  362. /*==================*/
  363. dtuple_t* tuple, /* in/out: a tuple with 3 fields */
  364. ulint i) /* in: a number < 512 */
  365. {
  366. ulint j;
  367. dfield_t* field;
  368. void* data = NULL;
  369. ulint len = 0;
  370. for (j = 0; j < 3; j++) {
  371. switch (i % 8) {
  372. case 0:
  373. data = ""; len = 0; break;
  374. case 1:
  375. data = "A"; len = 1; break;
  376. case 2:
  377. data = "AA"; len = 2; break;
  378. case 3:
  379. data = "AB"; len = 2; break;
  380. case 4:
  381. data = "B"; len = 1; break;
  382. case 5:
  383. data = "BA"; len = 2; break;
  384. case 6:
  385. data = "BB"; len = 2; break;
  386. case 7:
  387. len = UNIV_SQL_NULL; break;
  388. }
  389. field = dtuple_get_nth_field(tuple, 2 - j);
  390. dfield_set_data(field, data, len);
  391. dtype_set(dfield_get_type(field), DATA_VARCHAR,
  392. DATA_ENGLISH, 100, 0);
  393. i = i / 8;
  394. }
  395. ut_ad(dtuple_validate(tuple));
  396. }
  397. /*******************************************************************
  398. Generates a test tuple for B-tree speed tests. */
  399. void
  400. dtuple_gen_test_tuple3(
  401. /*===================*/
  402. dtuple_t* tuple, /* in/out: a tuple with >= 3 fields */
  403. ulint i, /* in: a number < 1000000 */
  404. ulint type, /* in: DTUPLE_TEST_FIXED30, ... */
  405. byte* buf) /* in: a buffer of size >= 16 bytes */
  406. {
  407. dfield_t* field;
  408. ulint third_size;
  409. ut_ad(tuple && buf);
  410. ut_ad(i < 1000000);
  411. field = dtuple_get_nth_field(tuple, 0);
  412. ut_strcpy((char*)buf, "0000000");
  413. buf[1] = (byte)('0' + (i / 100000) % 10);
  414. buf[2] = (byte)('0' + (i / 10000) % 10);
  415. buf[3] = (byte)('0' + (i / 1000) % 10);
  416. buf[4] = (byte)('0' + (i / 100) % 10);
  417. buf[5] = (byte)('0' + (i / 10) % 10);
  418. buf[6] = (byte)('0' + (i % 10));
  419. dfield_set_data(field, buf, 8);
  420. dtype_set(dfield_get_type(field), DATA_VARCHAR, DATA_ENGLISH, 100, 0);
  421. field = dtuple_get_nth_field(tuple, 1);
  422. i = i % 1000; /* ut_rnd_gen_ulint() % 1000000; */
  423. ut_strcpy((char*)buf + 8, "0000000");
  424. buf[9] = (byte)('0' + (i / 100000) % 10);
  425. buf[10] = (byte)('0' + (i / 10000) % 10);
  426. buf[11] = (byte)('0' + (i / 1000) % 10);
  427. buf[12] = (byte)('0' + (i / 100) % 10);
  428. buf[13] = (byte)('0' + (i / 10) % 10);
  429. buf[14] = (byte)('0' + (i % 10));
  430. dfield_set_data(field, buf + 8, 8);
  431. dtype_set(dfield_get_type(field), DATA_VARCHAR, DATA_ENGLISH, 100, 0);
  432. field = dtuple_get_nth_field(tuple, 2);
  433. data_rnd += 8757651;
  434. if (type == DTUPLE_TEST_FIXED30) {
  435. third_size = 30;
  436. } else if (type == DTUPLE_TEST_RND30) {
  437. third_size = data_rnd % 30;
  438. } else if (type == DTUPLE_TEST_RND3500) {
  439. third_size = data_rnd % 3500;
  440. } else if (type == DTUPLE_TEST_FIXED2000) {
  441. third_size = 2000;
  442. } else if (type == DTUPLE_TEST_FIXED3) {
  443. third_size = 3;
  444. } else {
  445. ut_error;
  446. }
  447. if (type == DTUPLE_TEST_FIXED30) {
  448. dfield_set_data(field,
  449. "12345678901234567890123456789", third_size);
  450. } else {
  451. dfield_set_data(field, data_buf, third_size);
  452. }
  453. dtype_set(dfield_get_type(field), DATA_VARCHAR, DATA_ENGLISH, 100, 0);
  454. ut_ad(dtuple_validate(tuple));
  455. }
  456. /*******************************************************************
  457. Generates a test tuple for B-tree speed tests. */
  458. void
  459. dtuple_gen_search_tuple3(
  460. /*=====================*/
  461. dtuple_t* tuple, /* in/out: a tuple with 1 or 2 fields */
  462. ulint i, /* in: a number < 1000000 */
  463. byte* buf) /* in: a buffer of size >= 16 bytes */
  464. {
  465. dfield_t* field;
  466. ut_ad(tuple && buf);
  467. ut_ad(i < 1000000);
  468. field = dtuple_get_nth_field(tuple, 0);
  469. ut_strcpy((char*)buf, "0000000");
  470. buf[1] = (byte)('0' + (i / 100000) % 10);
  471. buf[2] = (byte)('0' + (i / 10000) % 10);
  472. buf[3] = (byte)('0' + (i / 1000) % 10);
  473. buf[4] = (byte)('0' + (i / 100) % 10);
  474. buf[5] = (byte)('0' + (i / 10) % 10);
  475. buf[6] = (byte)('0' + (i % 10));
  476. dfield_set_data(field, buf, 8);
  477. dtype_set(dfield_get_type(field), DATA_VARCHAR, DATA_ENGLISH, 100, 0);
  478. if (dtuple_get_n_fields(tuple) == 1) {
  479. return;
  480. }
  481. field = dtuple_get_nth_field(tuple, 1);
  482. i = (i * 1000) % 1000000;
  483. ut_strcpy((char*)buf + 8, "0000000");
  484. buf[9] = (byte)('0' + (i / 100000) % 10);
  485. buf[10] = (byte)('0' + (i / 10000) % 10);
  486. buf[11] = (byte)('0' + (i / 1000) % 10);
  487. buf[12] = (byte)('0' + (i / 100) % 10);
  488. buf[13] = (byte)('0' + (i / 10) % 10);
  489. buf[14] = (byte)('0' + (i % 10));
  490. dfield_set_data(field, buf + 8, 8);
  491. dtype_set(dfield_get_type(field), DATA_VARCHAR, DATA_ENGLISH, 100, 0);
  492. ut_ad(dtuple_validate(tuple));
  493. }
  494. /*******************************************************************
  495. Generates a test tuple for TPC-A speed test. */
  496. void
  497. dtuple_gen_test_tuple_TPC_A(
  498. /*========================*/
  499. dtuple_t* tuple, /* in/out: a tuple with >= 3 fields */
  500. ulint i, /* in: a number < 10000 */
  501. byte* buf) /* in: a buffer of size >= 16 bytes */
  502. {
  503. dfield_t* field;
  504. ulint third_size;
  505. ut_ad(tuple && buf);
  506. ut_ad(i < 10000);
  507. field = dtuple_get_nth_field(tuple, 0);
  508. ut_strcpy((char*)buf, "0000");
  509. buf[0] = (byte)('0' + (i / 1000) % 10);
  510. buf[1] = (byte)('0' + (i / 100) % 10);
  511. buf[2] = (byte)('0' + (i / 10) % 10);
  512. buf[3] = (byte)('0' + (i % 10));
  513. dfield_set_data(field, buf, 5);
  514. dtype_set(dfield_get_type(field), DATA_VARCHAR, DATA_ENGLISH, 100, 0);
  515. field = dtuple_get_nth_field(tuple, 1);
  516. dfield_set_data(field, buf + 8, 5);
  517. dtype_set(dfield_get_type(field), DATA_VARCHAR, DATA_ENGLISH, 100, 0);
  518. field = dtuple_get_nth_field(tuple, 2);
  519. third_size = 90;
  520. dfield_set_data(field, data_buf, third_size);
  521. dtype_set(dfield_get_type(field), DATA_VARCHAR, DATA_ENGLISH, 100, 0);
  522. ut_ad(dtuple_validate(tuple));
  523. }
  524. /*******************************************************************
  525. Generates a test tuple for B-tree speed tests. */
  526. void
  527. dtuple_gen_search_tuple_TPC_A(
  528. /*==========================*/
  529. dtuple_t* tuple, /* in/out: a tuple with 1 field */
  530. ulint i, /* in: a number < 10000 */
  531. byte* buf) /* in: a buffer of size >= 16 bytes */
  532. {
  533. dfield_t* field;
  534. ut_ad(tuple && buf);
  535. ut_ad(i < 10000);
  536. field = dtuple_get_nth_field(tuple, 0);
  537. ut_strcpy((char*)buf, "0000");
  538. buf[0] = (byte)('0' + (i / 1000) % 10);
  539. buf[1] = (byte)('0' + (i / 100) % 10);
  540. buf[2] = (byte)('0' + (i / 10) % 10);
  541. buf[3] = (byte)('0' + (i % 10));
  542. dfield_set_data(field, buf, 5);
  543. dtype_set(dfield_get_type(field), DATA_VARCHAR, DATA_ENGLISH, 100, 0);
  544. ut_ad(dtuple_validate(tuple));
  545. }
  546. /*******************************************************************
  547. Generates a test tuple for TPC-C speed test. */
  548. void
  549. dtuple_gen_test_tuple_TPC_C(
  550. /*========================*/
  551. dtuple_t* tuple, /* in/out: a tuple with >= 12 fields */
  552. ulint i, /* in: a number < 100000 */
  553. byte* buf) /* in: a buffer of size >= 16 bytes */
  554. {
  555. dfield_t* field;
  556. ulint size;
  557. ulint j;
  558. ut_ad(tuple && buf);
  559. ut_ad(i < 100000);
  560. field = dtuple_get_nth_field(tuple, 0);
  561. buf[0] = (byte)('0' + (i / 10000) % 10);
  562. buf[1] = (byte)('0' + (i / 1000) % 10);
  563. buf[2] = (byte)('0' + (i / 100) % 10);
  564. buf[3] = (byte)('0' + (i / 10) % 10);
  565. buf[4] = (byte)('0' + (i % 10));
  566. dfield_set_data(field, buf, 5);
  567. dtype_set(dfield_get_type(field), DATA_VARCHAR, DATA_ENGLISH, 100, 0);
  568. field = dtuple_get_nth_field(tuple, 1);
  569. dfield_set_data(field, buf, 5);
  570. dtype_set(dfield_get_type(field), DATA_VARCHAR, DATA_ENGLISH, 100, 0);
  571. for (j = 0; j < 10; j++) {
  572. field = dtuple_get_nth_field(tuple, 2 + j);
  573. size = 24;
  574. dfield_set_data(field, data_buf, size);
  575. dtype_set(dfield_get_type(field), DATA_VARCHAR, DATA_ENGLISH,
  576. 100, 0);
  577. }
  578. ut_ad(dtuple_validate(tuple));
  579. }
  580. /*******************************************************************
  581. Generates a test tuple for B-tree speed tests. */
  582. void
  583. dtuple_gen_search_tuple_TPC_C(
  584. /*==========================*/
  585. dtuple_t* tuple, /* in/out: a tuple with 1 field */
  586. ulint i, /* in: a number < 100000 */
  587. byte* buf) /* in: a buffer of size >= 16 bytes */
  588. {
  589. dfield_t* field;
  590. ut_ad(tuple && buf);
  591. ut_ad(i < 100000);
  592. field = dtuple_get_nth_field(tuple, 0);
  593. buf[0] = (byte)('0' + (i / 10000) % 10);
  594. buf[1] = (byte)('0' + (i / 1000) % 10);
  595. buf[2] = (byte)('0' + (i / 100) % 10);
  596. buf[3] = (byte)('0' + (i / 10) % 10);
  597. buf[4] = (byte)('0' + (i % 10));
  598. dfield_set_data(field, buf, 5);
  599. dtype_set(dfield_get_type(field), DATA_VARCHAR, DATA_ENGLISH, 100, 0);
  600. ut_ad(dtuple_validate(tuple));
  601. }
  602. #endif /* notdefined */