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

MySQL数据库

开发平台:

Visual C++

  1. /***********************************************************************
  2. Comparison services for records
  3. (c) 1994-1996 Innobase Oy
  4. Created 7/1/1994 Heikki Tuuri
  5. ************************************************************************/
  6. #include "rem0cmp.h"
  7. #ifdef UNIV_NONINL
  8. #include "rem0cmp.ic"
  9. #endif
  10. /* ALPHABETICAL ORDER
  11. ==================
  12. The records are put into alphabetical order in the following
  13. way: let F be the first field where two records disagree.
  14. If there is a character in some position n where the the
  15. records disagree, the order is determined by comparison of
  16. the characters at position n, possibly after
  17. collating transformation. If there is no such character,
  18. but the corresponding fields have different lengths, then
  19. if the data type of the fields is paddable,
  20. shorter field is padded with a padding character. If the
  21. data type is not paddable, longer field is considered greater.
  22. Finally, the SQL null is bigger than any other value.
  23. At the present, the comparison functions return 0 in the case,
  24. where two records disagree only in the way that one 
  25. has more fields than the other. */
  26. /*****************************************************************
  27. Used in debug checking of cmp_dtuple_... .
  28. This function is used to compare a data tuple to a physical record. If
  29. dtuple has n fields then rec must have either m >= n fields, or it must
  30. differ from dtuple in some of the m fields rec has. */
  31. static
  32. int
  33. cmp_debug_dtuple_rec_with_match(
  34. /*============================*/
  35. /* out: 1, 0, -1, if dtuple is greater, equal, 
  36. less than rec, respectively, when only the 
  37. common first fields are compared */
  38. dtuple_t* dtuple, /* in: data tuple */
  39. rec_t* rec, /* in: physical record which differs from
  40. dtuple in some of the common fields, or which
  41. has an equal number or more fields than
  42. dtuple */
  43. ulint*   matched_fields);/* in/out: number of already completely 
  44. matched fields; when function returns,
  45. contains the value for current comparison */
  46. /*****************************************************************
  47. This function is used to compare two data fields for which the data type
  48. is such that we must use MySQL code to compare them. */
  49. int
  50. innobase_mysql_cmp(
  51. /*===============*/
  52. /* out: 1, 0, -1, if a is greater,
  53. equal, less than b, respectively */
  54. int mysql_type, /* in: MySQL type */ 
  55. unsigned char* a, /* in: data field */
  56. unsigned int a_length, /* in: data field length,
  57. not UNIV_SQL_NULL */
  58. unsigned char* b, /* in: data field */
  59. unsigned int b_length); /* in: data field length,
  60. not UNIV_SQL_NULL */
  61. /*****************************************************************
  62. Innobase uses this function is to compare two data fields for which the
  63. data type is such that we must compare whole fields. */
  64. static
  65. int
  66. cmp_whole_field(
  67. /*============*/
  68. /* out: 1, 0, -1, if a is greater,
  69. equal, less than b, respectively */
  70. dtype_t* type, /* in: data type */
  71. unsigned char* a, /* in: data field */
  72. unsigned int a_length, /* in: data field length,
  73. not UNIV_SQL_NULL */
  74. unsigned char* b, /* in: data field */
  75. unsigned int b_length) /* in: data field length,
  76. not UNIV_SQL_NULL */
  77. {
  78. float f_1;
  79. float f_2;
  80. double d_1;
  81. double d_2;
  82. int swap_flag = 1;
  83. ulint data_type;
  84. data_type = type->mtype;
  85. switch (data_type) {
  86.      case DATA_DECIMAL:
  87. /* Remove preceding spaces */
  88. for (; a_length && *a == ' '; a++, a_length--);
  89. for (; b_length && *b == ' '; b++, b_length--);
  90.        if (*a == '-') {
  91. if (*b != '-') {
  92.    return(-1);
  93.    }
  94. a++; b++;
  95. a_length--;
  96. b_length--;
  97. swap_flag = -1;
  98.        } else if (*b == '-') {
  99. return(1);
  100. }
  101.        while (a_length > 0 && (*a == '+' || *a == '0')) {
  102. a++; a_length--;
  103.        }
  104.        while (b_length > 0 && (*b == '+' || *b == '0')) {
  105. b++; b_length--;
  106.        }
  107.       
  108.        if (a_length != b_length) {
  109. if (a_length < b_length) {
  110. return(-swap_flag);
  111. }
  112. return(swap_flag);
  113. }
  114. while (a_length > 0 && *a == *b) {
  115. a++; b++; a_length--;
  116. }
  117. if (a_length == 0) {
  118. return(0);
  119. }
  120. if (*a > *b) {
  121. return(swap_flag);
  122. }
  123. return(-swap_flag);
  124.      case DATA_DOUBLE:
  125. d_1 = mach_double_read(a);
  126. d_2 = mach_double_read(b);
  127.        if (d_1 > d_2) {
  128.        return(1);
  129.        } else if (d_2 > d_1) {
  130.        return(-1);
  131.        }
  132.        return(0);
  133. case DATA_FLOAT:
  134. f_1 = mach_float_read(a);
  135. f_2 = mach_float_read(b);
  136.        if (f_1 > f_2) {
  137.        return(1);
  138.        } else if (f_2 > f_1) {
  139.        return(-1);
  140.        }
  141.        return(0);
  142. case DATA_VARMYSQL:
  143. case DATA_MYSQL:
  144. return(innobase_mysql_cmp(
  145. (int)(type->prtype & ~DATA_NOT_NULL),
  146. a, a_length, b, b_length));
  147. default:
  148. assert(0);
  149. }
  150. return(0);
  151. }
  152. /*****************************************************************
  153. This function is used to compare two data fields for which we know the
  154. data type. */
  155. int
  156. cmp_data_data_slow(
  157. /*===============*/
  158. /* out: 1, 0, -1, if data1 is greater, equal, 
  159. less than data2, respectively */
  160. dtype_t* cur_type,/* in: data type of the fields */
  161. byte* data1, /* in: data field (== a pointer to a memory
  162. buffer) */
  163. ulint len1, /* in: data field length or UNIV_SQL_NULL */
  164. byte* data2, /* in: data field (== a pointer to a memory
  165. buffer) */
  166. ulint len2) /* in: data field length or UNIV_SQL_NULL */
  167. {
  168. ulint data1_byte;
  169. ulint data2_byte;
  170. ulint cur_bytes;
  171. ut_ad(dtype_validate(cur_type));
  172. if (len1 == UNIV_SQL_NULL || len2 == UNIV_SQL_NULL) {
  173. if (len1 == len2) {
  174. return(0);
  175. }
  176. if (len1 == UNIV_SQL_NULL) {
  177. /* We define the SQL null to be the smallest possible
  178. value of a field in the alphabetical order */
  179. return(-1);
  180. }
  181. return(1);
  182. }
  183. if (cur_type->mtype >= DATA_FLOAT) {
  184. return(cmp_whole_field(cur_type, data1, len1, data2, len2));
  185. }
  186. /* Compare then the fields */
  187. cur_bytes = 0;
  188. for (;;) {
  189. if (len1 <= cur_bytes) {
  190. if (len2 <= cur_bytes) {
  191. return(0);
  192. }
  193. data1_byte = dtype_get_pad_char(cur_type);
  194. if (data1_byte == ULINT_UNDEFINED) {
  195. return(-1);
  196. }
  197. } else {
  198. data1_byte = *data1;
  199. }
  200. if (len2 <= cur_bytes) {
  201. data2_byte = dtype_get_pad_char(cur_type);
  202. if (data2_byte == ULINT_UNDEFINED) {
  203. return(1);
  204. }
  205. } else {
  206. data2_byte = *data2;
  207. }
  208. if (data1_byte == data2_byte) {
  209. /* If the bytes are equal, they will remain such even
  210. after the collation transformation below */
  211. goto next_byte;
  212. }
  213. if (cur_type->mtype <= DATA_CHAR) {
  214. data1_byte = dtype_collate(cur_type, data1_byte);
  215. data2_byte = dtype_collate(cur_type, data2_byte);
  216. }
  217. if (data1_byte > data2_byte) {
  218. return(1);
  219. } else if (data1_byte < data2_byte) {
  220. return(-1);
  221. }
  222. next_byte:
  223. /* Next byte */
  224. cur_bytes++;
  225. data1++;
  226. data2++;
  227. }
  228. return(0);
  229. }
  230. /*****************************************************************
  231. This function is used to compare a data tuple to a physical record.
  232. Only dtuple->n_fields_cmp first fields are taken into account for
  233. the the data tuple! If we denote by n = n_fields_cmp, then rec must
  234. have either m >= n fields, or it must differ from dtuple in some of
  235. the m fields rec has. */
  236. int
  237. cmp_dtuple_rec_with_match(
  238. /*======================*/
  239. /* out: 1, 0, -1, if dtuple is greater, equal, 
  240. less than rec, respectively, when only the 
  241. common first fields are compared */
  242. dtuple_t* dtuple, /* in: data tuple */
  243. rec_t* rec, /* in: physical record which differs from
  244. dtuple in some of the common fields, or which
  245. has an equal number or more fields than
  246. dtuple */
  247. ulint*   matched_fields, /* in/out: number of already completely 
  248. matched fields; when function returns,
  249. contains the value for current comparison */
  250. ulint*    matched_bytes) /* in/out: number of already matched 
  251. bytes within the first field not completely
  252. matched; when function returns, contains the
  253. value for current comparison */
  254. {
  255. dtype_t* cur_type; /* pointer to type of the current
  256. field in dtuple */
  257. dfield_t* dtuple_field; /* current field in logical record */
  258. ulint dtuple_f_len; /* the length of the current field 
  259. in the logical record */
  260. byte* dtuple_b_ptr; /* pointer to the current byte in 
  261. logical field data */
  262. ulint dtuple_byte; /* value of current byte to be compared 
  263. in dtuple*/
  264. ulint rec_f_len; /* length of current field in rec */
  265. byte* rec_b_ptr; /* pointer to the current byte in 
  266. rec field */
  267. ulint rec_byte; /* value of current byte to be 
  268. compared in rec */
  269. ulint cur_field; /* current field number */
  270. ulint cur_bytes;  /* number of already matched bytes 
  271. in current field */
  272. int ret = 3333; /* return value */
  273. ut_ad(dtuple && rec && matched_fields && matched_bytes);
  274. ut_ad(dtuple_check_typed(dtuple));
  275. cur_field = *matched_fields;
  276. cur_bytes = *matched_bytes;
  277. ut_ad(cur_field <= dtuple_get_n_fields_cmp(dtuple));
  278. ut_ad(cur_field <= rec_get_n_fields(rec));
  279. /* Match fields in a loop; stop if we run out of fields in dtuple */
  280. while (cur_field < dtuple_get_n_fields_cmp(dtuple)) {
  281. dtuple_field = dtuple_get_nth_field(dtuple, cur_field);
  282. cur_type = dfield_get_type(dtuple_field);
  283. dtuple_f_len = dfield_get_len(dtuple_field);
  284. rec_b_ptr = rec_get_nth_field(rec, cur_field, &rec_f_len);
  285. /* If we have matched yet 0 bytes, it may be that one or
  286. both the fields are SQL null, or the record or dtuple may be
  287. the predefined minimum record */
  288. if (cur_bytes == 0) {
  289. if (cur_field == 0) {
  290. if (rec_get_info_bits(rec)
  291.     & REC_INFO_MIN_REC_FLAG) {
  292. if (dtuple_get_info_bits(dtuple)
  293.          & REC_INFO_MIN_REC_FLAG) {
  294.      ret = 0;
  295.      } else {
  296.      ret = 1;
  297.      }
  298. goto order_resolved;
  299. }
  300. if (dtuple_get_info_bits(dtuple)
  301.     & REC_INFO_MIN_REC_FLAG) {
  302.        ret = -1;
  303. goto order_resolved;
  304. }
  305. }
  306.      if (dtuple_f_len == UNIV_SQL_NULL
  307.             || rec_f_len == UNIV_SQL_NULL) {
  308. if (dtuple_f_len == rec_f_len) {
  309. goto next_field;
  310. }
  311. if (rec_f_len == UNIV_SQL_NULL) {
  312. /* We define the SQL null to be the 
  313. smallest possible value of a field 
  314. in the alphabetical order */
  315. ret = 1;
  316. } else {
  317. ret = -1;
  318. }
  319. goto order_resolved;
  320. }
  321. }
  322. if (cur_type->mtype >= DATA_FLOAT) {
  323. ret = cmp_whole_field(cur_type,
  324. dfield_get_data(dtuple_field), dtuple_f_len,
  325. rec_b_ptr, rec_f_len);
  326. if (ret != 0) {
  327. cur_bytes = 0;
  328. goto order_resolved;
  329. } else {
  330. goto next_field;
  331. }
  332. }
  333. /* Set the pointers at the current byte */
  334. rec_b_ptr = rec_b_ptr + cur_bytes;
  335. dtuple_b_ptr = (byte*)dfield_get_data(dtuple_field) 
  336. + cur_bytes;
  337. /* Compare then the fields */
  338. for (;;) {
  339. if (rec_f_len <= cur_bytes) {
  340. if (dtuple_f_len <= cur_bytes) {
  341. goto next_field;
  342. }
  343. rec_byte = dtype_get_pad_char(cur_type);
  344. if (rec_byte == ULINT_UNDEFINED) {
  345. ret = 1;
  346. goto order_resolved;
  347. }
  348. } else {
  349. rec_byte = *rec_b_ptr;
  350. }
  351. if (dtuple_f_len <= cur_bytes) {
  352. dtuple_byte = dtype_get_pad_char(cur_type);
  353. if (dtuple_byte == ULINT_UNDEFINED) {
  354. ret = -1;
  355. goto order_resolved;
  356. }
  357. } else {
  358. dtuple_byte = *dtuple_b_ptr;
  359. }
  360. if (dtuple_byte == rec_byte) {
  361. /* If the bytes are equal, they will
  362. remain such even after the collation
  363. transformation below */
  364. goto next_byte;
  365. }
  366. if (cur_type->mtype <= DATA_CHAR) {
  367. rec_byte = dtype_collate(cur_type, rec_byte);
  368. dtuple_byte = dtype_collate(cur_type, 
  369. dtuple_byte);
  370. }
  371. if (dtuple_byte > rec_byte) {
  372. ret = 1;
  373. goto order_resolved;
  374. } else if (dtuple_byte < rec_byte) {
  375. ret = -1;
  376. goto order_resolved;
  377. }
  378. next_byte:
  379. /* Next byte */
  380. cur_bytes++;
  381. rec_b_ptr++;
  382. dtuple_b_ptr++;
  383. }
  384. next_field:
  385. cur_field++;
  386. cur_bytes = 0;
  387. }
  388. ut_ad(cur_bytes == 0);
  389. ret = 0; /* If we ran out of fields, dtuple was equal to rec
  390. up to the common fields */
  391. order_resolved:
  392. ut_ad((ret >= - 1) && (ret <= 1));
  393. ut_ad(ret == cmp_debug_dtuple_rec_with_match(dtuple, rec,
  394. matched_fields));
  395. ut_ad(*matched_fields == cur_field); /* In the debug version, the
  396. above cmp_debug_... sets
  397. *matched_fields to a value */
  398. *matched_fields = cur_field;
  399. *matched_bytes = cur_bytes;
  400. return(ret);
  401. }
  402. /******************************************************************
  403. Compares a data tuple to a physical record. */
  404. int
  405. cmp_dtuple_rec(
  406. /*===========*/
  407. /* out: 1, 0, -1, if dtuple is greater, equal, 
  408. less than rec, respectively; see the comments
  409. for cmp_dtuple_rec_with_match */
  410. dtuple_t*  dtuple, /* in: data tuple */
  411. rec_t*    rec) /* in: physical record */
  412. {
  413. ulint matched_fields = 0;
  414. ulint matched_bytes = 0;
  415. return(cmp_dtuple_rec_with_match(dtuple, rec, &matched_fields,
  416. &matched_bytes));
  417. }
  418. /******************************************************************
  419. Checks if a dtuple is a prefix of a record. The last field in dtuple
  420. is allowed to be a prefix of the corresponding field in the record. */
  421. ibool
  422. cmp_dtuple_is_prefix_of_rec(
  423. /*========================*/
  424. /* out: TRUE if prefix */
  425. dtuple_t*  dtuple, /* in: data tuple */
  426. rec_t*    rec) /* in: physical record */
  427. {
  428. ulint n_fields;
  429. ulint matched_fields = 0;
  430. ulint matched_bytes = 0;
  431. n_fields = dtuple_get_n_fields(dtuple);
  432. if (n_fields > rec_get_n_fields(rec)) {
  433. return(FALSE);
  434. }
  435. cmp_dtuple_rec_with_match(dtuple, rec, &matched_fields,
  436. &matched_bytes);
  437. if (matched_fields == n_fields) {
  438. return(TRUE);
  439. }
  440. if (matched_fields == n_fields - 1
  441. && matched_bytes == dfield_get_len(
  442. dtuple_get_nth_field(dtuple, n_fields - 1))) {
  443. return(TRUE);
  444. }
  445. return(FALSE);
  446. }
  447. /******************************************************************
  448. Compares a prefix of a data tuple to a prefix of a physical record for
  449. equality. If there are less fields in rec than parameter n_fields, FALSE
  450. is returned. NOTE that n_fields_cmp of dtuple does not affect this
  451. comparison. */
  452. ibool
  453. cmp_dtuple_rec_prefix_equal(
  454. /*========================*/
  455. /* out: TRUE if equal */
  456. dtuple_t* dtuple, /* in: data tuple */
  457. rec_t* rec, /* in: physical record */
  458. ulint n_fields) /* in: number of fields which should be 
  459. compared; must not exceed the number of 
  460. fields in dtuple */
  461. {
  462. ulint matched_fields = 0;
  463. ulint matched_bytes = 0;
  464. ut_ad(n_fields <= dtuple_get_n_fields(dtuple));
  465. if (rec_get_n_fields(rec) < n_fields) {
  466. return(FALSE);
  467. }
  468. cmp_dtuple_rec_with_match(dtuple, rec, &matched_fields, 
  469. &matched_bytes);
  470. if (matched_fields >= n_fields) {
  471. return(TRUE);
  472. }
  473. return(FALSE);
  474. }
  475. /*****************************************************************
  476. This function is used to compare two physical records. Only the common
  477. first fields are compared. */
  478. int
  479. cmp_rec_rec_with_match(
  480. /*===================*/
  481. /* out: 1, 0 , -1 if rec1 is greater, equal,
  482. less, respectively, than rec2; only the common
  483. first fields are compared */
  484. rec_t* rec1, /* in: physical record */
  485. rec_t* rec2, /* in: physical record */
  486. dict_index_t* index, /* in: data dictionary index */
  487. ulint*   matched_fields, /* in/out: number of already completely 
  488. matched fields; when the function returns,
  489. contains the value the for current
  490. comparison */
  491. ulint*    matched_bytes) /* in/out: number of already matched 
  492. bytes within the first field not completely
  493. matched; when the function returns, contains
  494. the value for the current comparison */
  495. {
  496. dtype_t* cur_type; /* pointer to type struct of the
  497. current field in index */
  498. ulint rec1_n_fields; /* the number of fields in rec */
  499. ulint rec1_f_len; /* length of current field in rec */
  500. byte* rec1_b_ptr; /* pointer to the current byte in rec field */
  501. ulint rec1_byte; /* value of current byte to be compared in
  502. rec */
  503. ulint rec2_n_fields; /* the number of fields in rec */
  504. ulint rec2_f_len; /* length of current field in rec */
  505. byte* rec2_b_ptr; /* pointer to the current byte in rec field */
  506. ulint rec2_byte; /* value of current byte to be compared in
  507. rec */
  508. ulint cur_field; /* current field number */
  509. ulint cur_bytes;  /* number of already matched bytes in current
  510. field */
  511. int ret = 3333; /* return value */
  512. ut_ad(rec1 && rec2 && index);
  513. rec1_n_fields = rec_get_n_fields(rec1);
  514. rec2_n_fields = rec_get_n_fields(rec2);
  515. cur_field = *matched_fields;
  516. cur_bytes = *matched_bytes;
  517. /* Match fields in a loop; stop if we run out of fields in either
  518. record */
  519. while ((cur_field < rec1_n_fields) && (cur_field < rec2_n_fields)) {
  520. if (index->type & DICT_UNIVERSAL) {
  521. cur_type = dtype_binary;
  522. } else {
  523. cur_type = dict_col_get_type(
  524.       dict_field_get_col(
  525. dict_index_get_nth_field(index, cur_field)));
  526. }
  527. rec1_b_ptr = rec_get_nth_field(rec1, cur_field, &rec1_f_len);
  528. rec2_b_ptr = rec_get_nth_field(rec2, cur_field, &rec2_f_len);
  529. if (cur_bytes == 0) {
  530. if (cur_field == 0) {
  531. /* Test if rec is the predefined minimum
  532. record */
  533. if (rec_get_info_bits(rec1)
  534. & REC_INFO_MIN_REC_FLAG) {
  535. if (rec_get_info_bits(rec2) 
  536.     & REC_INFO_MIN_REC_FLAG) {
  537. ret = 0;
  538. } else {
  539. ret = -1;
  540. }
  541. goto order_resolved;
  542. } else if (rec_get_info_bits(rec2) 
  543.    & REC_INFO_MIN_REC_FLAG) {
  544. ret = 1;
  545. goto order_resolved;
  546. }
  547.      if (rec1_f_len == UNIV_SQL_NULL
  548.             || rec2_f_len == UNIV_SQL_NULL) {
  549. if (rec1_f_len == rec2_f_len) {
  550. goto next_field;
  551. } else if (rec2_f_len == UNIV_SQL_NULL) {
  552. /* We define the SQL null to be the 
  553. smallest possible value of a field 
  554. in the alphabetical order */
  555. ret = 1;
  556. } else {
  557. ret = -1;
  558. }
  559. goto order_resolved;
  560. }
  561. }
  562. if (cur_type->mtype >= DATA_FLOAT) {
  563. ret = cmp_whole_field(cur_type,
  564. rec1_b_ptr, rec1_f_len,
  565. rec2_b_ptr, rec2_f_len);
  566. if (ret != 0) {
  567. cur_bytes = 0;
  568. goto order_resolved;
  569. } else {
  570. goto next_field;
  571. }
  572. }
  573. /* Set the pointers at the current byte */
  574. rec1_b_ptr = rec1_b_ptr + cur_bytes;
  575. rec2_b_ptr = rec2_b_ptr + cur_bytes;
  576. /* Compare then the fields */
  577. for (;;) {
  578. if (rec2_f_len <= cur_bytes) {
  579. if (rec1_f_len <= cur_bytes) {
  580. goto next_field;
  581. }
  582. rec2_byte = dtype_get_pad_char(cur_type);
  583. if (rec2_byte == ULINT_UNDEFINED) {
  584. ret = 1;
  585. goto order_resolved;
  586. }
  587. } else {
  588. rec2_byte = *rec2_b_ptr;
  589. }
  590. if (rec1_f_len <= cur_bytes) {
  591. rec1_byte = dtype_get_pad_char(cur_type);
  592. if (rec1_byte == ULINT_UNDEFINED) {
  593. ret = -1;
  594. goto order_resolved;
  595. }
  596. } else {
  597. rec1_byte = *rec1_b_ptr;
  598. }
  599. if (rec1_byte == rec2_byte) {
  600. /* If the bytes are equal, they will remain
  601. such even after the collation transformation 
  602. below */
  603. goto next_byte;
  604. }
  605. if (cur_type->mtype <= DATA_CHAR) {
  606. rec1_byte = dtype_collate(cur_type, rec1_byte);
  607. rec2_byte = dtype_collate(cur_type, rec2_byte);
  608. }
  609. if (rec1_byte < rec2_byte) {
  610. ret = -1;
  611. goto order_resolved;
  612. } else if (rec1_byte > rec2_byte) {
  613. ret = 1;
  614. goto order_resolved;
  615. }
  616. next_byte:
  617. /* Next byte */
  618. cur_bytes++;
  619. rec1_b_ptr++;
  620. rec2_b_ptr++;
  621. }
  622. next_field:
  623. cur_field++;
  624. cur_bytes = 0;
  625. }
  626. ut_ad(cur_bytes == 0);
  627. ret = 0; /* If we ran out of fields, rec1 was equal to rec2 up
  628. to the common fields */
  629. order_resolved:
  630. ut_ad((ret >= - 1) && (ret <= 1));
  631. *matched_fields = cur_field;
  632. *matched_bytes = cur_bytes;
  633. return(ret);
  634. }
  635. /*****************************************************************
  636. Used in debug checking of cmp_dtuple_... .
  637. This function is used to compare a data tuple to a physical record. If
  638. dtuple has n fields then rec must have either m >= n fields, or it must
  639. differ from dtuple in some of the m fields rec has. */
  640. static
  641. int
  642. cmp_debug_dtuple_rec_with_match(
  643. /*============================*/
  644. /* out: 1, 0, -1, if dtuple is greater, equal, 
  645. less than rec, respectively, when only the 
  646. common first fields are compared */
  647. dtuple_t* dtuple, /* in: data tuple */
  648. rec_t* rec, /* in: physical record which differs from
  649. dtuple in some of the common fields, or which
  650. has an equal number or more fields than
  651. dtuple */
  652. ulint*   matched_fields) /* in/out: number of already completely 
  653. matched fields; when function returns,
  654. contains the value for current comparison */
  655. {
  656. dtype_t* cur_type; /* pointer to type of the current
  657. field in dtuple */
  658. dfield_t* dtuple_field; /* current field in logical record */
  659. ulint dtuple_f_len; /* the length of the current field 
  660. in the logical record */
  661. byte* dtuple_f_data; /* pointer to the current logical
  662. field data */
  663. ulint rec_f_len; /* length of current field in rec */
  664. byte* rec_f_data; /* pointer to the current rec field */
  665. int ret = 3333; /* return value */
  666. ulint cur_field; /* current field number */
  667. ut_ad(dtuple && rec && matched_fields);
  668. ut_ad(dtuple_check_typed(dtuple));
  669. ut_ad(*matched_fields <= dtuple_get_n_fields_cmp(dtuple));
  670. ut_ad(*matched_fields <= rec_get_n_fields(rec));
  671. cur_field = *matched_fields;
  672. if (cur_field == 0) {
  673. if (rec_get_info_bits(rec) & REC_INFO_MIN_REC_FLAG) {
  674. if (dtuple_get_info_bits(dtuple)
  675.          & REC_INFO_MIN_REC_FLAG) {
  676. ret = 0;
  677. } else {
  678. ret = 1;
  679. }
  680. goto order_resolved;
  681. }
  682. if (dtuple_get_info_bits(dtuple) & REC_INFO_MIN_REC_FLAG) {
  683.   ret = -1;
  684. goto order_resolved;
  685. }
  686. }
  687. /* Match fields in a loop; stop if we run out of fields in dtuple */
  688. while (cur_field < dtuple_get_n_fields_cmp(dtuple)) {
  689. dtuple_field = dtuple_get_nth_field(dtuple, cur_field);
  690. cur_type = dfield_get_type(dtuple_field);
  691. dtuple_f_data = dfield_get_data(dtuple_field);
  692. dtuple_f_len = dfield_get_len(dtuple_field);
  693. rec_f_data = rec_get_nth_field(rec, cur_field, &rec_f_len);
  694. ret = cmp_data_data(cur_type, dtuple_f_data, dtuple_f_len,
  695. rec_f_data, rec_f_len);
  696. if (ret != 0) {
  697. goto order_resolved;
  698. cur_field++;
  699. }
  700. ret = 0; /* If we ran out of fields, dtuple was equal to rec
  701. up to the common fields */
  702. order_resolved:
  703. ut_ad((ret >= - 1) && (ret <= 1));
  704. *matched_fields = cur_field;
  705. return(ret);
  706. }