You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

728 lines
28 KiB

20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
branches/zip: Initialize dfield_t::ext as soon as possible. This should fix the bugs introduced in r1591. row_rec_to_index_entry_low(): Clear "n_ext". Do not allow it to be NULL. Add const qualifier to dict_index_t*. row_rec_to_index_entry(): Add the parameters "offsets" and "n_ext". btr_cur_optimistic_update(): Add an assertion that there are no externally stored columns. Remove the unreachable call to btr_cur_unmark_extern_fields() and the preceding unnecessary call to rec_get_offsets(). btr_push_update_extern_fields(): Remove the parameters index, offsets. Only report the additional externally stored columns of the update vector. row_build(), trx_undo_rec_get_partial_row(): Flag externally stored columns also with dfield_set_ext(). rec_copy_prefix_to_dtuple(): Assert that there are no externally stored columns in the prefix. row_build_row_ref(): Note and assert that the index is a secondary index, and assert that there are no externally stored columns. row_build_row_ref_fast(): Assert that there are no externally stored columns. rec_offs_get_n_alloc(): Expose the function. row_build_row_ref_in_tuple(): Assert that there are no externally stored columns in a record of a secondary index. row_build_row_ref_from_row(): Assert that there are no externally stored columns. row_upd_check_references_constraints(): Add the parameter offsets, to avoid a redundant call to rec_get_offsets(). row_upd_del_mark_clust_rec(): Add the parameter offsets. Remove duplicated code. row_ins_index_entry_set_vals(): Copy the external storage flag. sel_pop_prefetched_row(): Assert that there are no externally stored columns. row_scan_and_check_index(): Copy offsets to a temporary heap across the invocation of row_rec_to_index_entry().
18 years ago
20 years ago
branches/zip: Initialize dfield_t::ext as soon as possible. This should fix the bugs introduced in r1591. row_rec_to_index_entry_low(): Clear "n_ext". Do not allow it to be NULL. Add const qualifier to dict_index_t*. row_rec_to_index_entry(): Add the parameters "offsets" and "n_ext". btr_cur_optimistic_update(): Add an assertion that there are no externally stored columns. Remove the unreachable call to btr_cur_unmark_extern_fields() and the preceding unnecessary call to rec_get_offsets(). btr_push_update_extern_fields(): Remove the parameters index, offsets. Only report the additional externally stored columns of the update vector. row_build(), trx_undo_rec_get_partial_row(): Flag externally stored columns also with dfield_set_ext(). rec_copy_prefix_to_dtuple(): Assert that there are no externally stored columns in the prefix. row_build_row_ref(): Note and assert that the index is a secondary index, and assert that there are no externally stored columns. row_build_row_ref_fast(): Assert that there are no externally stored columns. rec_offs_get_n_alloc(): Expose the function. row_build_row_ref_in_tuple(): Assert that there are no externally stored columns in a record of a secondary index. row_build_row_ref_from_row(): Assert that there are no externally stored columns. row_upd_check_references_constraints(): Add the parameter offsets, to avoid a redundant call to rec_get_offsets(). row_upd_del_mark_clust_rec(): Add the parameter offsets. Remove duplicated code. row_ins_index_entry_set_vals(): Copy the external storage flag. sel_pop_prefetched_row(): Assert that there are no externally stored columns. row_scan_and_check_index(): Copy offsets to a temporary heap across the invocation of row_rec_to_index_entry().
18 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
  1. /******************************************************
  2. The index tree cursor
  3. (c) 1994-1996 Innobase Oy
  4. Created 10/16/1994 Heikki Tuuri
  5. *******************************************************/
  6. #ifndef btr0cur_h
  7. #define btr0cur_h
  8. #include "univ.i"
  9. #include "dict0dict.h"
  10. #include "data0data.h"
  11. #include "page0cur.h"
  12. #include "btr0types.h"
  13. #include "que0types.h"
  14. #include "row0types.h"
  15. #include "ha0ha.h"
  16. /* Mode flags for btr_cur operations; these can be ORed */
  17. #define BTR_NO_UNDO_LOG_FLAG 1 /* do no undo logging */
  18. #define BTR_NO_LOCKING_FLAG 2 /* do no record lock checking */
  19. #define BTR_KEEP_SYS_FLAG 4 /* sys fields will be found from the
  20. update vector or inserted entry */
  21. #define BTR_CUR_ADAPT
  22. #define BTR_CUR_HASH_ADAPT
  23. #ifdef UNIV_DEBUG
  24. /*************************************************************
  25. Returns the page cursor component of a tree cursor. */
  26. UNIV_INLINE
  27. page_cur_t*
  28. btr_cur_get_page_cur(
  29. /*=================*/
  30. /* out: pointer to page cursor
  31. component */
  32. const btr_cur_t* cursor);/* in: tree cursor */
  33. #else /* UNIV_DEBUG */
  34. # define btr_cur_get_page_cur(cursor) (&(cursor)->page_cur)
  35. #endif /* UNIV_DEBUG */
  36. /*************************************************************
  37. Returns the buffer block on which the tree cursor is positioned. */
  38. UNIV_INLINE
  39. buf_block_t*
  40. btr_cur_get_block(
  41. /*==============*/
  42. /* out: pointer to buffer block */
  43. btr_cur_t* cursor);/* in: tree cursor */
  44. /*************************************************************
  45. Returns the record pointer of a tree cursor. */
  46. UNIV_INLINE
  47. rec_t*
  48. btr_cur_get_rec(
  49. /*============*/
  50. /* out: pointer to record */
  51. btr_cur_t* cursor);/* in: tree cursor */
  52. /*************************************************************
  53. Returns the compressed page on which the tree cursor is positioned. */
  54. UNIV_INLINE
  55. page_zip_des_t*
  56. btr_cur_get_page_zip(
  57. /*=================*/
  58. /* out: pointer to compressed page,
  59. or NULL if the page is not compressed */
  60. btr_cur_t* cursor);/* in: tree cursor */
  61. /*************************************************************
  62. Invalidates a tree cursor by setting record pointer to NULL. */
  63. UNIV_INLINE
  64. void
  65. btr_cur_invalidate(
  66. /*===============*/
  67. btr_cur_t* cursor);/* in: tree cursor */
  68. /*************************************************************
  69. Returns the page of a tree cursor. */
  70. UNIV_INLINE
  71. page_t*
  72. btr_cur_get_page(
  73. /*=============*/
  74. /* out: pointer to page */
  75. btr_cur_t* cursor);/* in: tree cursor */
  76. /*************************************************************
  77. Returns the index of a cursor. */
  78. UNIV_INLINE
  79. dict_index_t*
  80. btr_cur_get_index(
  81. /*==============*/
  82. /* out: index */
  83. btr_cur_t* cursor);/* in: B-tree cursor */
  84. /*************************************************************
  85. Positions a tree cursor at a given record. */
  86. UNIV_INLINE
  87. void
  88. btr_cur_position(
  89. /*=============*/
  90. dict_index_t* index, /* in: index */
  91. rec_t* rec, /* in: record in tree */
  92. buf_block_t* block, /* in: buffer block of rec */
  93. btr_cur_t* cursor);/* in: cursor */
  94. /************************************************************************
  95. Searches an index tree and positions a tree cursor on a given level.
  96. NOTE: n_fields_cmp in tuple must be set so that it cannot be compared
  97. to node pointer page number fields on the upper levels of the tree!
  98. Note that if mode is PAGE_CUR_LE, which is used in inserts, then
  99. cursor->up_match and cursor->low_match both will have sensible values.
  100. If mode is PAGE_CUR_GE, then up_match will a have a sensible value. */
  101. void
  102. btr_cur_search_to_nth_level(
  103. /*========================*/
  104. dict_index_t* index, /* in: index */
  105. ulint level, /* in: the tree level of search */
  106. const dtuple_t* tuple, /* in: data tuple; NOTE: n_fields_cmp in
  107. tuple must be set so that it cannot get
  108. compared to the node ptr page number field! */
  109. ulint mode, /* in: PAGE_CUR_L, ...;
  110. NOTE that if the search is made using a unique
  111. prefix of a record, mode should be PAGE_CUR_LE,
  112. not PAGE_CUR_GE, as the latter may end up on
  113. the previous page of the record! Inserts
  114. should always be made using PAGE_CUR_LE to
  115. search the position! */
  116. ulint latch_mode, /* in: BTR_SEARCH_LEAF, ..., ORed with
  117. BTR_INSERT and BTR_ESTIMATE;
  118. cursor->left_block is used to store a pointer
  119. to the left neighbor page, in the cases
  120. BTR_SEARCH_PREV and BTR_MODIFY_PREV;
  121. NOTE that if has_search_latch
  122. is != 0, we maybe do not have a latch set
  123. on the cursor page, we assume
  124. the caller uses his search latch
  125. to protect the record! */
  126. btr_cur_t* cursor, /* in/out: tree cursor; the cursor page is
  127. s- or x-latched, but see also above! */
  128. ulint has_search_latch,/* in: latch mode the caller
  129. currently has on btr_search_latch:
  130. RW_S_LATCH, or 0 */
  131. mtr_t* mtr); /* in: mtr */
  132. /*********************************************************************
  133. Opens a cursor at either end of an index. */
  134. void
  135. btr_cur_open_at_index_side(
  136. /*=======================*/
  137. ibool from_left, /* in: TRUE if open to the low end,
  138. FALSE if to the high end */
  139. dict_index_t* index, /* in: index */
  140. ulint latch_mode, /* in: latch mode */
  141. btr_cur_t* cursor, /* in: cursor */
  142. mtr_t* mtr); /* in: mtr */
  143. /**************************************************************************
  144. Positions a cursor at a randomly chosen position within a B-tree. */
  145. void
  146. btr_cur_open_at_rnd_pos(
  147. /*====================*/
  148. dict_index_t* index, /* in: index */
  149. ulint latch_mode, /* in: BTR_SEARCH_LEAF, ... */
  150. btr_cur_t* cursor, /* in/out: B-tree cursor */
  151. mtr_t* mtr); /* in: mtr */
  152. /*****************************************************************
  153. Tries to perform an insert to a page in an index tree, next to cursor.
  154. It is assumed that mtr holds an x-latch on the page. The operation does
  155. not succeed if there is too little space on the page. If there is just
  156. one record on the page, the insert will always succeed; this is to
  157. prevent trying to split a page with just one record. */
  158. ulint
  159. btr_cur_optimistic_insert(
  160. /*======================*/
  161. /* out: DB_SUCCESS, DB_WAIT_LOCK,
  162. DB_FAIL, or error number */
  163. ulint flags, /* in: undo logging and locking flags: if not
  164. zero, the parameters index and thr should be
  165. specified */
  166. btr_cur_t* cursor, /* in: cursor on page after which to insert;
  167. cursor stays valid */
  168. dtuple_t* entry, /* in/out: entry to insert */
  169. rec_t** rec, /* out: pointer to inserted record if
  170. succeed */
  171. big_rec_t** big_rec,/* out: big rec vector whose fields have to
  172. be stored externally by the caller, or
  173. NULL */
  174. ulint n_ext, /* in: number of externally stored columns */
  175. que_thr_t* thr, /* in: query thread or NULL */
  176. mtr_t* mtr); /* in: mtr; if this function returns
  177. DB_SUCCESS on a leaf page of a secondary
  178. index in a compressed tablespace, the
  179. mtr must be committed before latching
  180. any further pages */
  181. /*****************************************************************
  182. Performs an insert on a page of an index tree. It is assumed that mtr
  183. holds an x-latch on the tree and on the cursor page. If the insert is
  184. made on the leaf level, to avoid deadlocks, mtr must also own x-latches
  185. to brothers of page, if those brothers exist. */
  186. ulint
  187. btr_cur_pessimistic_insert(
  188. /*=======================*/
  189. /* out: DB_SUCCESS or error number */
  190. ulint flags, /* in: undo logging and locking flags: if not
  191. zero, the parameter thr should be
  192. specified; if no undo logging is specified,
  193. then the caller must have reserved enough
  194. free extents in the file space so that the
  195. insertion will certainly succeed */
  196. btr_cur_t* cursor, /* in: cursor after which to insert;
  197. cursor stays valid */
  198. dtuple_t* entry, /* in/out: entry to insert */
  199. rec_t** rec, /* out: pointer to inserted record if
  200. succeed */
  201. big_rec_t** big_rec,/* out: big rec vector whose fields have to
  202. be stored externally by the caller, or
  203. NULL */
  204. ulint n_ext, /* in: number of externally stored columns */
  205. que_thr_t* thr, /* in: query thread or NULL */
  206. mtr_t* mtr); /* in: mtr */
  207. /*****************************************************************
  208. Updates a record when the update causes no size changes in its fields. */
  209. ulint
  210. btr_cur_update_in_place(
  211. /*====================*/
  212. /* out: DB_SUCCESS or error number */
  213. ulint flags, /* in: undo logging and locking flags */
  214. btr_cur_t* cursor, /* in: cursor on the record to update;
  215. cursor stays valid and positioned on the
  216. same record */
  217. const upd_t* update, /* in: update vector */
  218. ulint cmpl_info,/* in: compiler info on secondary index
  219. updates */
  220. que_thr_t* thr, /* in: query thread */
  221. mtr_t* mtr); /* in: mtr; must be committed before
  222. latching any further pages */
  223. /*****************************************************************
  224. Tries to update a record on a page in an index tree. It is assumed that mtr
  225. holds an x-latch on the page. The operation does not succeed if there is too
  226. little space on the page or if the update would result in too empty a page,
  227. so that tree compression is recommended. */
  228. ulint
  229. btr_cur_optimistic_update(
  230. /*======================*/
  231. /* out: DB_SUCCESS, or DB_OVERFLOW if the
  232. updated record does not fit, DB_UNDERFLOW
  233. if the page would become too empty, or
  234. DB_ZIP_OVERFLOW if there is not enough
  235. space left on the compressed page */
  236. ulint flags, /* in: undo logging and locking flags */
  237. btr_cur_t* cursor, /* in: cursor on the record to update;
  238. cursor stays valid and positioned on the
  239. same record */
  240. const upd_t* update, /* in: update vector; this must also
  241. contain trx id and roll ptr fields */
  242. ulint cmpl_info,/* in: compiler info on secondary index
  243. updates */
  244. que_thr_t* thr, /* in: query thread */
  245. mtr_t* mtr); /* in: mtr; must be committed before
  246. latching any further pages */
  247. /*****************************************************************
  248. Performs an update of a record on a page of a tree. It is assumed
  249. that mtr holds an x-latch on the tree and on the cursor page. If the
  250. update is made on the leaf level, to avoid deadlocks, mtr must also
  251. own x-latches to brothers of page, if those brothers exist. */
  252. ulint
  253. btr_cur_pessimistic_update(
  254. /*=======================*/
  255. /* out: DB_SUCCESS or error code */
  256. ulint flags, /* in: undo logging, locking, and rollback
  257. flags */
  258. btr_cur_t* cursor, /* in: cursor on the record to update */
  259. mem_heap_t** heap, /* in/out: pointer to memory heap, or NULL */
  260. big_rec_t** big_rec,/* out: big rec vector whose fields have to
  261. be stored externally by the caller, or NULL */
  262. const upd_t* update, /* in: update vector; this is allowed also
  263. contain trx id and roll ptr fields, but
  264. the values in update vector have no effect */
  265. ulint cmpl_info,/* in: compiler info on secondary index
  266. updates */
  267. que_thr_t* thr, /* in: query thread */
  268. mtr_t* mtr); /* in: mtr; must be committed before
  269. latching any further pages */
  270. /***************************************************************
  271. Marks a clustered index record deleted. Writes an undo log record to
  272. undo log on this delete marking. Writes in the trx id field the id
  273. of the deleting transaction, and in the roll ptr field pointer to the
  274. undo log record created. */
  275. ulint
  276. btr_cur_del_mark_set_clust_rec(
  277. /*===========================*/
  278. /* out: DB_SUCCESS, DB_LOCK_WAIT, or error
  279. number */
  280. ulint flags, /* in: undo logging and locking flags */
  281. btr_cur_t* cursor, /* in: cursor */
  282. ibool val, /* in: value to set */
  283. que_thr_t* thr, /* in: query thread */
  284. mtr_t* mtr); /* in: mtr */
  285. /***************************************************************
  286. Sets a secondary index record delete mark to TRUE or FALSE. */
  287. ulint
  288. btr_cur_del_mark_set_sec_rec(
  289. /*=========================*/
  290. /* out: DB_SUCCESS, DB_LOCK_WAIT, or error
  291. number */
  292. ulint flags, /* in: locking flag */
  293. btr_cur_t* cursor, /* in: cursor */
  294. ibool val, /* in: value to set */
  295. que_thr_t* thr, /* in: query thread */
  296. mtr_t* mtr); /* in: mtr */
  297. /***************************************************************
  298. Sets a secondary index record delete mark to FALSE. This function is
  299. only used by the insert buffer insert merge mechanism. */
  300. void
  301. btr_cur_del_unmark_for_ibuf(
  302. /*========================*/
  303. rec_t* rec, /* in/out: record to delete unmark */
  304. page_zip_des_t* page_zip, /* in/out: compressed page
  305. corresponding to rec, or NULL
  306. when the tablespace is
  307. uncompressed */
  308. mtr_t* mtr); /* in: mtr */
  309. /*****************************************************************
  310. Tries to compress a page of the tree if it seems useful. It is assumed
  311. that mtr holds an x-latch on the tree and on the cursor page. To avoid
  312. deadlocks, mtr must also own x-latches to brothers of page, if those
  313. brothers exist. NOTE: it is assumed that the caller has reserved enough
  314. free extents so that the compression will always succeed if done! */
  315. ibool
  316. btr_cur_compress_if_useful(
  317. /*=======================*/
  318. /* out: TRUE if compression occurred */
  319. btr_cur_t* cursor, /* in: cursor on the page to compress;
  320. cursor does not stay valid if compression
  321. occurs */
  322. mtr_t* mtr); /* in: mtr */
  323. /***********************************************************
  324. Removes the record on which the tree cursor is positioned. It is assumed
  325. that the mtr has an x-latch on the page where the cursor is positioned,
  326. but no latch on the whole tree. */
  327. ibool
  328. btr_cur_optimistic_delete(
  329. /*======================*/
  330. /* out: TRUE if success, i.e., the page
  331. did not become too empty */
  332. btr_cur_t* cursor, /* in: cursor on the record to delete;
  333. cursor stays valid: if deletion succeeds,
  334. on function exit it points to the successor
  335. of the deleted record */
  336. mtr_t* mtr); /* in: mtr */
  337. /*****************************************************************
  338. Removes the record on which the tree cursor is positioned. Tries
  339. to compress the page if its fillfactor drops below a threshold
  340. or if it is the only page on the level. It is assumed that mtr holds
  341. an x-latch on the tree and on the cursor page. To avoid deadlocks,
  342. mtr must also own x-latches to brothers of page, if those brothers
  343. exist. */
  344. ibool
  345. btr_cur_pessimistic_delete(
  346. /*=======================*/
  347. /* out: TRUE if compression occurred */
  348. ulint* err, /* out: DB_SUCCESS or DB_OUT_OF_FILE_SPACE;
  349. the latter may occur because we may have
  350. to update node pointers on upper levels,
  351. and in the case of variable length keys
  352. these may actually grow in size */
  353. ibool has_reserved_extents, /* in: TRUE if the
  354. caller has already reserved enough free
  355. extents so that he knows that the operation
  356. will succeed */
  357. btr_cur_t* cursor, /* in: cursor on the record to delete;
  358. if compression does not occur, the cursor
  359. stays valid: it points to successor of
  360. deleted record on function exit */
  361. ibool in_rollback,/* in: TRUE if called in rollback */
  362. mtr_t* mtr); /* in: mtr */
  363. /***************************************************************
  364. Parses a redo log record of updating a record in-place. */
  365. byte*
  366. btr_cur_parse_update_in_place(
  367. /*==========================*/
  368. /* out: end of log record or NULL */
  369. byte* ptr, /* in: buffer */
  370. byte* end_ptr,/* in: buffer end */
  371. page_t* page, /* in/out: page or NULL */
  372. page_zip_des_t* page_zip,/* in/out: compressed page, or NULL */
  373. dict_index_t* index); /* in: index corresponding to page */
  374. /********************************************************************
  375. Parses the redo log record for delete marking or unmarking of a clustered
  376. index record. */
  377. byte*
  378. btr_cur_parse_del_mark_set_clust_rec(
  379. /*=================================*/
  380. /* out: end of log record or NULL */
  381. byte* ptr, /* in: buffer */
  382. byte* end_ptr,/* in: buffer end */
  383. page_t* page, /* in/out: page or NULL */
  384. page_zip_des_t* page_zip,/* in/out: compressed page, or NULL */
  385. dict_index_t* index); /* in: index corresponding to page */
  386. /********************************************************************
  387. Parses the redo log record for delete marking or unmarking of a secondary
  388. index record. */
  389. byte*
  390. btr_cur_parse_del_mark_set_sec_rec(
  391. /*===============================*/
  392. /* out: end of log record or NULL */
  393. byte* ptr, /* in: buffer */
  394. byte* end_ptr,/* in: buffer end */
  395. page_t* page, /* in/out: page or NULL */
  396. page_zip_des_t* page_zip);/* in/out: compressed page, or NULL */
  397. /***********************************************************************
  398. Estimates the number of rows in a given index range. */
  399. ib_longlong
  400. btr_estimate_n_rows_in_range(
  401. /*=========================*/
  402. /* out: estimated number of rows */
  403. dict_index_t* index, /* in: index */
  404. const dtuple_t* tuple1, /* in: range start, may also be empty tuple */
  405. ulint mode1, /* in: search mode for range start */
  406. const dtuple_t* tuple2, /* in: range end, may also be empty tuple */
  407. ulint mode2); /* in: search mode for range end */
  408. /***********************************************************************
  409. Estimates the number of different key values in a given index, for
  410. each n-column prefix of the index where n <= dict_index_get_n_unique(index).
  411. The estimates are stored in the array index->stat_n_diff_key_vals. */
  412. void
  413. btr_estimate_number_of_different_key_vals(
  414. /*======================================*/
  415. dict_index_t* index); /* in: index */
  416. /***********************************************************************
  417. Marks not updated extern fields as not-owned by this record. The ownership
  418. is transferred to the updated record which is inserted elsewhere in the
  419. index tree. In purge only the owner of externally stored field is allowed
  420. to free the field. */
  421. void
  422. btr_cur_mark_extern_inherited_fields(
  423. /*=================================*/
  424. page_zip_des_t* page_zip,/* in/out: compressed page whose uncompressed
  425. part will be updated, or NULL */
  426. rec_t* rec, /* in/out: record in a clustered index */
  427. dict_index_t* index, /* in: index of the page */
  428. const ulint* offsets,/* in: array returned by rec_get_offsets() */
  429. const upd_t* update, /* in: update vector */
  430. mtr_t* mtr); /* in: mtr, or NULL if not logged */
  431. /***********************************************************************
  432. The complement of the previous function: in an update entry may inherit
  433. some externally stored fields from a record. We must mark them as inherited
  434. in entry, so that they are not freed in a rollback. */
  435. void
  436. btr_cur_mark_dtuple_inherited_extern(
  437. /*=================================*/
  438. dtuple_t* entry, /* in/out: updated entry to be
  439. inserted to clustered index */
  440. const upd_t* update); /* in: update vector */
  441. /***********************************************************************
  442. Marks all extern fields in a dtuple as owned by the record. */
  443. void
  444. btr_cur_unmark_dtuple_extern_fields(
  445. /*================================*/
  446. dtuple_t* entry); /* in/out: clustered index entry */
  447. /***********************************************************************
  448. Stores the fields in big_rec_vec to the tablespace and puts pointers to
  449. them in rec. The extern flags in rec will have to be set beforehand.
  450. The fields are stored on pages allocated from leaf node
  451. file segment of the index tree. */
  452. ulint
  453. btr_store_big_rec_extern_fields(
  454. /*============================*/
  455. /* out: DB_SUCCESS or error */
  456. dict_index_t* index, /* in: index of rec; the index tree
  457. MUST be X-latched */
  458. buf_block_t* rec_block, /* in/out: block containing rec */
  459. rec_t* rec, /* in: record */
  460. const ulint* offsets, /* in: rec_get_offsets(rec, index);
  461. the "external storage" flags in offsets
  462. will not correspond to rec when
  463. this function returns */
  464. big_rec_t* big_rec_vec, /* in: vector containing fields
  465. to be stored externally */
  466. mtr_t* local_mtr); /* in: mtr containing the latch to
  467. rec and to the tree */
  468. /***********************************************************************
  469. Frees the space in an externally stored field to the file space
  470. management if the field in data is owned the externally stored field,
  471. in a rollback we may have the additional condition that the field must
  472. not be inherited. */
  473. void
  474. btr_free_externally_stored_field(
  475. /*=============================*/
  476. dict_index_t* index, /* in: index of the data, the index
  477. tree MUST be X-latched; if the tree
  478. height is 1, then also the root page
  479. must be X-latched! (this is relevant
  480. in the case this function is called
  481. from purge where 'data' is located on
  482. an undo log page, not an index
  483. page) */
  484. byte* field_ref, /* in/out: field reference */
  485. const rec_t* rec, /* in: record containing field_ref, for
  486. page_zip_write_blob_ptr(), or NULL */
  487. const ulint* offsets, /* in: rec_get_offsets(rec, index),
  488. or NULL */
  489. page_zip_des_t* page_zip, /* in: compressed page corresponding
  490. to rec, or NULL if rec == NULL */
  491. ulint i, /* in: field number of field_ref;
  492. ignored if rec == NULL */
  493. ibool do_not_free_inherited,/* in: TRUE if called in a
  494. rollback and we do not want to free
  495. inherited fields */
  496. mtr_t* local_mtr); /* in: mtr containing the latch to
  497. data an an X-latch to the index
  498. tree */
  499. /***********************************************************************
  500. Copies the prefix of an externally stored field of a record. Parameter
  501. data contains a pointer to 'internally' stored part of the field:
  502. possibly some data, and the reference to the externally stored part in
  503. the last BTR_EXTERN_FIELD_REF_SIZE bytes of data. */
  504. ulint
  505. btr_copy_externally_stored_field_prefix(
  506. /*====================================*/
  507. /* out: the length of the copied field */
  508. byte* buf, /* out: the field, or a prefix of it */
  509. ulint len, /* in: length of buf, in bytes */
  510. ulint zip_size,/* in: nonzero=compressed BLOB page size,
  511. zero for uncompressed BLOBs */
  512. const byte* data, /* in: 'internally' stored part of the
  513. field containing also the reference to
  514. the external part */
  515. ulint local_len);/* in: length of data, in bytes */
  516. /***********************************************************************
  517. Copies an externally stored field of a record to mem heap. */
  518. byte*
  519. btr_rec_copy_externally_stored_field(
  520. /*=================================*/
  521. /* out: the field copied to heap */
  522. const rec_t* rec, /* in: record */
  523. const ulint* offsets,/* in: array returned by rec_get_offsets() */
  524. ulint zip_size,/* in: nonzero=compressed BLOB page size,
  525. zero for uncompressed BLOBs */
  526. ulint no, /* in: field number */
  527. ulint* len, /* out: length of the field */
  528. mem_heap_t* heap); /* in: mem heap */
  529. /***********************************************************************
  530. Flags the data tuple fields that are marked as extern storage in the
  531. update vector. We use this function to remember which fields we must
  532. mark as extern storage in a record inserted for an update. */
  533. ulint
  534. btr_push_update_extern_fields(
  535. /*==========================*/
  536. /* out: number of flagged external columns */
  537. dtuple_t* tuple, /* in/out: data tuple */
  538. const upd_t* update) /* in: update vector */
  539. __attribute__((nonnull));
  540. /*######################################################################*/
  541. /* In the pessimistic delete, if the page data size drops below this
  542. limit, merging it to a neighbor is tried */
  543. #define BTR_CUR_PAGE_COMPRESS_LIMIT (UNIV_PAGE_SIZE / 2)
  544. /* A slot in the path array. We store here info on a search path down the
  545. tree. Each slot contains data on a single level of the tree. */
  546. typedef struct btr_path_struct btr_path_t;
  547. struct btr_path_struct{
  548. ulint nth_rec; /* index of the record
  549. where the page cursor stopped on
  550. this level (index in alphabetical
  551. order); value ULINT_UNDEFINED
  552. denotes array end */
  553. ulint n_recs; /* number of records on the page */
  554. };
  555. #define BTR_PATH_ARRAY_N_SLOTS 250 /* size of path array (in slots) */
  556. /* The tree cursor: the definition appears here only for the compiler
  557. to know struct size! */
  558. struct btr_cur_struct {
  559. dict_index_t* index; /* index where positioned */
  560. page_cur_t page_cur; /* page cursor */
  561. buf_block_t* left_block; /* this field is used to store
  562. a pointer to the left neighbor
  563. page, in the cases
  564. BTR_SEARCH_PREV and
  565. BTR_MODIFY_PREV */
  566. /*------------------------------*/
  567. que_thr_t* thr; /* this field is only used when
  568. btr_cur_search_... is called for an
  569. index entry insertion: the calling
  570. query thread is passed here to be
  571. used in the insert buffer */
  572. /*------------------------------*/
  573. /* The following fields are used in btr_cur_search... to pass
  574. information: */
  575. ulint flag; /* BTR_CUR_HASH, BTR_CUR_HASH_FAIL,
  576. BTR_CUR_BINARY, or
  577. BTR_CUR_INSERT_TO_IBUF */
  578. ulint tree_height; /* Tree height if the search is done
  579. for a pessimistic insert or update
  580. operation */
  581. ulint up_match; /* If the search mode was PAGE_CUR_LE,
  582. the number of matched fields to the
  583. the first user record to the right of
  584. the cursor record after
  585. btr_cur_search_...;
  586. for the mode PAGE_CUR_GE, the matched
  587. fields to the first user record AT THE
  588. CURSOR or to the right of it;
  589. NOTE that the up_match and low_match
  590. values may exceed the correct values
  591. for comparison to the adjacent user
  592. record if that record is on a
  593. different leaf page! (See the note in
  594. row_ins_duplicate_key.) */
  595. ulint up_bytes; /* number of matched bytes to the
  596. right at the time cursor positioned;
  597. only used internally in searches: not
  598. defined after the search */
  599. ulint low_match; /* if search mode was PAGE_CUR_LE,
  600. the number of matched fields to the
  601. first user record AT THE CURSOR or
  602. to the left of it after
  603. btr_cur_search_...;
  604. NOT defined for PAGE_CUR_GE or any
  605. other search modes; see also the NOTE
  606. in up_match! */
  607. ulint low_bytes; /* number of matched bytes to the
  608. right at the time cursor positioned;
  609. only used internally in searches: not
  610. defined after the search */
  611. ulint n_fields; /* prefix length used in a hash
  612. search if hash_node != NULL */
  613. ulint n_bytes; /* hash prefix bytes if hash_node !=
  614. NULL */
  615. ulint fold; /* fold value used in the search if
  616. flag is BTR_CUR_HASH */
  617. /*------------------------------*/
  618. btr_path_t* path_arr; /* in estimating the number of
  619. rows in range, we store in this array
  620. information of the path through
  621. the tree */
  622. };
  623. /* Values for the flag documenting the used search method */
  624. #define BTR_CUR_HASH 1 /* successful shortcut using the hash
  625. index */
  626. #define BTR_CUR_HASH_FAIL 2 /* failure using hash, success using
  627. binary search: the misleading hash
  628. reference is stored in the field
  629. hash_node, and might be necessary to
  630. update */
  631. #define BTR_CUR_BINARY 3 /* success using the binary search */
  632. #define BTR_CUR_INSERT_TO_IBUF 4 /* performed the intended insert to
  633. the insert buffer */
  634. /* If pessimistic delete fails because of lack of file space,
  635. there is still a good change of success a little later: try this many times,
  636. and sleep this many microseconds in between */
  637. #define BTR_CUR_RETRY_DELETE_N_TIMES 100
  638. #define BTR_CUR_RETRY_SLEEP_TIME 50000
  639. /* The reference in a field for which data is stored on a different page.
  640. The reference is at the end of the 'locally' stored part of the field.
  641. 'Locally' means storage in the index record.
  642. We store locally a long enough prefix of each column so that we can determine
  643. the ordering parts of each index record without looking into the externally
  644. stored part. */
  645. /*--------------------------------------*/
  646. #define BTR_EXTERN_SPACE_ID 0 /* space id where stored */
  647. #define BTR_EXTERN_PAGE_NO 4 /* page no where stored */
  648. #define BTR_EXTERN_OFFSET 8 /* offset of BLOB header
  649. on that page */
  650. #define BTR_EXTERN_LEN 12 /* 8 bytes containing the
  651. length of the externally
  652. stored part of the BLOB.
  653. The 2 highest bits are
  654. reserved to the flags below. */
  655. /*--------------------------------------*/
  656. /* #define BTR_EXTERN_FIELD_REF_SIZE 20 // moved to btr0types.h */
  657. /* The highest bit of BTR_EXTERN_LEN (i.e., the highest bit of the byte
  658. at lowest address) is set to 1 if this field does not 'own' the externally
  659. stored field; only the owner field is allowed to free the field in purge!
  660. If the 2nd highest bit is 1 then it means that the externally stored field
  661. was inherited from an earlier version of the row. In rollback we are not
  662. allowed to free an inherited external field. */
  663. #define BTR_EXTERN_OWNER_FLAG 128
  664. #define BTR_EXTERN_INHERITED_FLAG 64
  665. extern ulint btr_cur_n_non_sea;
  666. extern ulint btr_cur_n_sea;
  667. extern ulint btr_cur_n_non_sea_old;
  668. extern ulint btr_cur_n_sea_old;
  669. /* A BLOB field reference full of zero, for use in assertions and tests.
  670. Initially, BLOB field references are set to zero, in
  671. dtuple_convert_big_rec(). */
  672. extern const byte field_ref_zero[BTR_EXTERN_FIELD_REF_SIZE];
  673. #ifndef UNIV_NONINL
  674. #include "btr0cur.ic"
  675. #endif
  676. #endif