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

MySQL数据库

开发平台:

Visual C++

  1. /**********************************************************************
  2. Data dictionary system
  3. (c) 1996 Innobase Oy
  4. Created 1/8/1996 Heikki Tuuri
  5. ***********************************************************************/
  6. #include "dict0load.h"
  7. #include "trx0undo.h"
  8. #include "trx0sys.h"
  9. #include "rem0rec.h"
  10. /*************************************************************************
  11. Gets the column data type. */
  12. UNIV_INLINE
  13. dtype_t*
  14. dict_col_get_type(
  15. /*==============*/
  16. dict_col_t* col)
  17. {
  18. ut_ad(col);
  19. return(&col->type);
  20. }
  21. /*************************************************************************
  22. Gets the column number. */
  23. UNIV_INLINE
  24. ulint
  25. dict_col_get_no(
  26. /*============*/
  27. dict_col_t* col)
  28. {
  29. ut_ad(col);
  30. return(col->ind);
  31. }
  32. /*************************************************************************
  33. Gets the column position in the clustered index. */
  34. UNIV_INLINE
  35. ulint
  36. dict_col_get_clust_pos(
  37. /*===================*/
  38. dict_col_t* col)
  39. {
  40. ut_ad(col);
  41. return(col->clust_pos);
  42. }
  43. /************************************************************************
  44. Gets the first index on the table (the clustered index). */
  45. UNIV_INLINE
  46. dict_index_t*
  47. dict_table_get_first_index(
  48. /*=======================*/
  49. /* out: index, NULL if none exists */
  50. dict_table_t* table) /* in: table */
  51. {
  52. ut_ad(table);
  53. ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
  54. return(UT_LIST_GET_FIRST(table->indexes));
  55. }
  56. /************************************************************************
  57. Gets the next index on the table. */
  58. UNIV_INLINE
  59. dict_index_t*
  60. dict_table_get_next_index(
  61. /*======================*/
  62. /* out: index, NULL if none left */
  63. dict_index_t* index) /* in: index */
  64. {
  65. ut_ad(index);
  66. ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
  67. return(UT_LIST_GET_NEXT(indexes, index));
  68. }
  69. /************************************************************************
  70. Gets the number of user-defined columns in a table in the dictionary
  71. cache. */
  72. UNIV_INLINE
  73. ulint
  74. dict_table_get_n_user_cols(
  75. /*=======================*/
  76. /* out: number of user-defined (e.g., not
  77. ROW_ID) columns of a table */
  78. dict_table_t* table) /* in: table */
  79. {
  80. ut_ad(table);
  81. ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
  82. ut_ad(table->cached);
  83. return(table->n_cols - DATA_N_SYS_COLS);
  84. }
  85. /************************************************************************
  86. Gets the number of system columns in a table in the dictionary cache. */
  87. UNIV_INLINE
  88. ulint
  89. dict_table_get_n_sys_cols(
  90. /*======================*/
  91. /* out: number of system (e.g.,
  92. ROW_ID) columns of a table */
  93. dict_table_t* table) /* in: table */
  94. {
  95. ut_ad(table);
  96. ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
  97. ut_ad(table->cached);
  98. return(DATA_N_SYS_COLS);
  99. }
  100. /************************************************************************
  101. Gets the number of all columns (also system) in a table in the dictionary
  102. cache. */
  103. UNIV_INLINE
  104. ulint
  105. dict_table_get_n_cols(
  106. /*==================*/
  107. /* out: number of columns of a table */
  108. dict_table_t* table) /* in: table */
  109. {
  110. ut_ad(table);
  111. ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
  112. ut_ad(table->cached);
  113. return(table->n_cols);
  114. }
  115. /************************************************************************
  116. Gets the nth column of a table. */
  117. UNIV_INLINE
  118. dict_col_t*
  119. dict_table_get_nth_col(
  120. /*===================*/
  121. /* out: pointer to column object */
  122. dict_table_t* table, /* in: table */
  123. ulint pos) /* in: position of column */
  124. {
  125. ut_ad(table);
  126. ut_ad(pos < table->n_def);
  127. ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
  128. return((table->cols) + pos);
  129. }
  130. /************************************************************************
  131. Gets the given system column of a table. */
  132. UNIV_INLINE
  133. dict_col_t*
  134. dict_table_get_sys_col(
  135. /*===================*/
  136. /* out: pointer to column object */
  137. dict_table_t* table, /* in: table */
  138. ulint sys) /* in: DATA_ROW_ID, ... */
  139. {
  140. dict_col_t* col;
  141. ut_ad(table);
  142. ut_ad(sys < DATA_N_SYS_COLS);
  143. ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
  144. col = dict_table_get_nth_col(table, table->n_cols 
  145.    - DATA_N_SYS_COLS + sys);
  146. ut_ad(col->type.mtype == DATA_SYS);
  147. ut_ad(col->type.prtype == sys);
  148. return(col);
  149. }
  150. /************************************************************************
  151. Gets the given system column number of a table. */
  152. UNIV_INLINE
  153. ulint
  154. dict_table_get_sys_col_no(
  155. /*======================*/
  156. /* out: column number */
  157. dict_table_t* table, /* in: table */
  158. ulint sys) /* in: DATA_ROW_ID, ... */
  159. {
  160. ut_ad(table);
  161. ut_ad(sys < DATA_N_SYS_COLS);
  162. ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
  163. return(table->n_cols - DATA_N_SYS_COLS + sys);
  164. }
  165. /************************************************************************
  166. Gets the number of fields in the internal representation of an index,
  167. including fields added by the dictionary system. */
  168. UNIV_INLINE
  169. ulint
  170. dict_index_get_n_fields(
  171. /*====================*/
  172. /* out: number of fields */
  173. dict_index_t* index) /* in: an internal representation of index
  174. (in the dictionary cache) */
  175. {
  176. ut_ad(index);
  177. ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
  178. ut_ad(index->cached);
  179. return(index->n_fields);
  180. }
  181. /************************************************************************
  182. Gets the number of fields in the internal representation of an index
  183. that uniquely determine the position of an index entry in the index, if
  184. we do not take multiversioning into account: in the B-tree use the value
  185. returned by dict_index_get_n_unique_in_tree. */
  186. UNIV_INLINE
  187. ulint
  188. dict_index_get_n_unique(
  189. /*====================*/
  190. /* out: number of fields */
  191. dict_index_t* index) /* in: an internal representation of index
  192. (in the dictionary cache) */
  193. {
  194. ut_ad(index);
  195. ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
  196. ut_ad(index->cached);
  197. return(index->n_uniq);
  198. }
  199. /************************************************************************
  200. Gets the number of fields in the internal representation of an index
  201. which uniquely determine the position of an index entry in the index, if
  202. we also take multiversioning into account. */
  203. UNIV_INLINE
  204. ulint
  205. dict_index_get_n_unique_in_tree(
  206. /*============================*/
  207. /* out: number of fields */
  208. dict_index_t* index) /* in: an internal representation of index
  209. (in the dictionary cache) */
  210. {
  211. ut_ad(index);
  212. ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
  213. ut_ad(index->cached);
  214. if (index->type & DICT_CLUSTERED) {
  215. return(dict_index_get_n_unique(index));
  216. }
  217. return(dict_index_get_n_fields(index));
  218. }
  219. /************************************************************************
  220. Gets the number of user-defined ordering fields in the index. In the internal
  221. representation of clustered indexes we add the row id to the ordering fields
  222. to make a clustered index unique, but this function returns the number of
  223. fields the user defined in the index as ordering fields. */
  224. UNIV_INLINE
  225. ulint
  226. dict_index_get_n_ordering_defined_by_user(
  227. /*======================================*/
  228. /* out: number of fields */
  229. dict_index_t* index) /* in: an internal representation of index
  230. (in the dictionary cache) */
  231. {
  232. return(index->n_user_defined_cols);
  233. }
  234. /************************************************************************
  235. Gets the nth field of an index. */
  236. UNIV_INLINE
  237. dict_field_t*
  238. dict_index_get_nth_field(
  239. /*=====================*/
  240. /* out: pointer to field object */
  241. dict_index_t* index, /* in: index */
  242. ulint pos) /* in: position of field */
  243. {
  244. ut_ad(index);
  245. ut_ad(pos < index->n_def);
  246. ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
  247. return((index->fields) + pos);
  248. }
  249. /************************************************************************
  250. Returns the position of a system column in an index. */
  251. UNIV_INLINE
  252. ulint
  253. dict_index_get_sys_col_pos(
  254. /*=======================*/
  255. /* out: position, ULINT_UNDEFINED if not
  256. contained */
  257. dict_index_t* index, /* in: index */
  258. ulint type) /* in: DATA_ROW_ID, ... */
  259. {
  260. dict_col_t* col;
  261. ut_ad(index);
  262. ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
  263. ut_ad(!(index->type & DICT_UNIVERSAL));
  264. col = dict_table_get_sys_col(index->table, type);
  265. if (index->type & DICT_CLUSTERED) {
  266. return(col->clust_pos);
  267. }
  268. return(dict_index_get_nth_col_pos(index,
  269. dict_table_get_sys_col_no(index->table, type)));
  270. }
  271. /************************************************************************
  272. Gets the value of a system column in a clustered index record. The clustered
  273. index must contain the system column: if the index is unique, row id is
  274. not contained there! */
  275. UNIV_INLINE
  276. dulint
  277. dict_index_rec_get_sys_col(
  278. /*=======================*/
  279. /* out: system column value */
  280. dict_index_t* index, /* in: clustered index describing the record */
  281. ulint type, /* in: column type: DATA_ROLL_PTR, ... */
  282. rec_t* rec) /* in: record */
  283. {
  284. ulint pos;
  285. byte* field;
  286. ulint len;
  287. ut_ad(index);
  288. ut_ad(index->type & DICT_CLUSTERED);
  289. pos = dict_index_get_sys_col_pos(index, type);
  290. ut_ad(pos != ULINT_UNDEFINED);
  291. field = rec_get_nth_field(rec, pos, &len);
  292. if (type == DATA_ROLL_PTR) {
  293. ut_ad(len == 7);
  294. return(trx_read_roll_ptr(field));
  295. } else if ((type == DATA_ROW_ID) || (type == DATA_MIX_ID)) {
  296. return(mach_dulint_read_compressed(field));
  297. } else {
  298. ut_ad(type == DATA_TRX_ID);
  299. return(trx_read_trx_id(field));
  300. }
  301. }
  302. /*************************************************************************
  303. Gets the index tree where the index is stored. */
  304. UNIV_INLINE
  305. dict_tree_t*
  306. dict_index_get_tree(
  307. /*================*/
  308. /* out: index tree */
  309. dict_index_t* index) /* in: index */
  310. {
  311. ut_ad(index);
  312. ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
  313. return(index->tree);
  314. }
  315. /*************************************************************************
  316. Gets the field order criterion. */
  317. UNIV_INLINE
  318. ulint
  319. dict_field_get_order(
  320. /*=================*/
  321. dict_field_t* field)
  322. {
  323. ut_ad(field);
  324. return(field->order);
  325. }
  326. /*************************************************************************
  327. Gets the field column. */
  328. UNIV_INLINE
  329. dict_col_t*
  330. dict_field_get_col(
  331. /*===============*/
  332. dict_field_t* field)
  333. {
  334. ut_ad(field);
  335. return(field->col);
  336. }
  337. /************************************************************************
  338. Gets pointer to the nth field data type in an index. */
  339. UNIV_INLINE
  340. dtype_t*
  341. dict_index_get_nth_type(
  342. /*====================*/
  343. /* out: data type */
  344. dict_index_t* index, /* in: index */
  345. ulint pos) /* in: position of the field */
  346. {
  347. return(dict_col_get_type(dict_field_get_col(
  348. dict_index_get_nth_field(index, pos))));
  349. }
  350. /************************************************************************
  351. Gets the column number the nth field in an index. */
  352. UNIV_INLINE
  353. ulint
  354. dict_index_get_nth_col_no(
  355. /*======================*/
  356. /* out: column number */
  357. dict_index_t* index, /* in: index */
  358. ulint pos) /* in: position of the field */
  359. {
  360. return(dict_col_get_no(dict_field_get_col(
  361. dict_index_get_nth_field(index, pos))));
  362. }
  363. /*************************************************************************
  364. Gets the space id of the root of the index tree. */
  365. UNIV_INLINE
  366. ulint
  367. dict_tree_get_space(
  368. /*================*/
  369. /* out: space id */
  370. dict_tree_t* tree) /* in: tree */
  371. {
  372. ut_ad(tree);
  373. ut_ad(tree->magic_n == DICT_TREE_MAGIC_N);
  374. return(tree->space);
  375. }
  376. /*************************************************************************
  377. Sets the space id of the root of the index tree. */
  378. UNIV_INLINE
  379. void
  380. dict_tree_set_space(
  381. /*================*/
  382. dict_tree_t* tree, /* in: tree */
  383. ulint space) /* in: space id */
  384. {
  385. ut_ad(tree);
  386. ut_ad(tree->magic_n == DICT_TREE_MAGIC_N);
  387. tree->space = space;
  388. }
  389. /*************************************************************************
  390. Gets the page number of the root of the index tree. */
  391. UNIV_INLINE
  392. ulint
  393. dict_tree_get_page(
  394. /*===============*/
  395. /* out: page number */
  396. dict_tree_t* tree) /* in: tree */
  397. {
  398. ut_ad(tree);
  399. ut_ad(tree->magic_n == DICT_TREE_MAGIC_N);
  400. return(tree->page);
  401. }
  402. /*************************************************************************
  403. Sets the page number of the root of index tree. */
  404. UNIV_INLINE
  405. void
  406. dict_tree_set_page(
  407. /*===============*/
  408. dict_tree_t* tree, /* in: tree */
  409. ulint page) /* in: page number */
  410. {
  411. ut_ad(tree);
  412. ut_ad(tree->magic_n == DICT_TREE_MAGIC_N);
  413. tree->page = page;
  414. }
  415. /*************************************************************************
  416. Gets the type of the index tree. */
  417. UNIV_INLINE
  418. ulint
  419. dict_tree_get_type(
  420. /*===============*/
  421. /* out: type */
  422. dict_tree_t* tree) /* in: tree */
  423. {
  424. ut_ad(tree);
  425. ut_ad(tree->magic_n == DICT_TREE_MAGIC_N);
  426. return(tree->type);
  427. }
  428. /*************************************************************************
  429. Gets the read-write lock of the index tree. */
  430. UNIV_INLINE
  431. rw_lock_t*
  432. dict_tree_get_lock(
  433. /*===============*/
  434. /* out: read-write lock */
  435. dict_tree_t* tree) /* in: tree */
  436. {
  437. ut_ad(tree);
  438. ut_ad(tree->magic_n == DICT_TREE_MAGIC_N);
  439. return(&(tree->lock));
  440. }
  441. /************************************************************************
  442. Returns free space reserved for future updates of records. This is
  443. relevant only in the case of many consecutive inserts, as updates
  444. which make the records bigger might fragment the index. */
  445. UNIV_INLINE
  446. ulint
  447. dict_tree_get_space_reserve(
  448. /*========================*/
  449. /* out: number of free bytes on page,
  450. reserved for updates */
  451. dict_tree_t* tree) /* in: a tree */
  452. {
  453. ut_ad(tree);
  454. UT_NOT_USED(tree);
  455. return(UNIV_PAGE_SIZE / 16);
  456. }
  457. /**************************************************************************
  458. Gets a table; loads it to the dictionary cache if necessary. A low-level
  459. function. */
  460. UNIV_INLINE
  461. dict_table_t*
  462. dict_table_get_low(
  463. /*===============*/
  464. /* out: table, NULL if not found */
  465. char* table_name) /* in: table name */
  466. {
  467. dict_table_t* table;
  468. ulint table_fold;
  469. ut_ad(table_name);
  470. ut_ad(mutex_own(&(dict_sys->mutex)));
  471. /* Look for the table name in the hash table */
  472. table_fold = ut_fold_string(table_name);
  473. HASH_SEARCH(name_hash, dict_sys->table_hash, table_fold, table,
  474. ut_strcmp(table->name, table_name) == 0);
  475. if (table == NULL) {
  476. table = dict_load_table(table_name);
  477. }
  478. return(table);
  479. }
  480. /**************************************************************************
  481. Returns a stored procedure object and memoryfixes it. */
  482. UNIV_INLINE
  483. dict_proc_t*
  484. dict_procedure_get(
  485. /*===============*/
  486. /* out: procedure, NULL if does not exist */
  487. char* proc_name, /* in: table name */
  488. trx_t* trx) /* in: transaction handle or NULL */
  489. {
  490. dict_proc_t* proc;
  491. ulint name_fold;
  492. UT_NOT_USED(trx);
  493. mutex_enter(&(dict_sys->mutex));
  494. /* Look for the table name in the hash table */
  495. name_fold = ut_fold_string(proc_name);
  496. HASH_SEARCH(name_hash, dict_sys->procedure_hash, name_fold, proc,
  497. ut_strcmp(proc->name, proc_name) == 0);
  498. if (proc != NULL) {
  499. proc->mem_fix++;
  500. }
  501. mutex_exit(&(dict_sys->mutex));
  502. return(proc);
  503. }
  504. /**************************************************************************
  505. Returns a table object, based on table id, and memoryfixes it. */
  506. UNIV_INLINE
  507. dict_table_t*
  508. dict_table_get_on_id_low(
  509. /*=====================*/
  510. /* out: table, NULL if does not exist */
  511. dulint table_id, /* in: table id */
  512. trx_t* trx) /* in: transaction handle */
  513. {
  514. dict_table_t* table;
  515. ulint fold;
  516. UT_NOT_USED(trx);
  517. /* Look for the table name in the hash table */
  518. fold = ut_fold_dulint(table_id);
  519. HASH_SEARCH(id_hash, dict_sys->table_id_hash, fold, table,
  520. ut_dulint_cmp(table->id, table_id) == 0);
  521. if (table == NULL) {
  522. table = dict_load_table_on_id(table_id);
  523. }
  524. if (table != NULL) {
  525. table->mem_fix++;
  526. /* lock_push(trx, table, LOCK_DICT_MEM_FIX) */
  527. }
  528. /* TODO: should get the type information from MySQL */
  529. return(table);
  530. }
  531. /**************************************************************************
  532. Releases a table from being memoryfixed. Currently this has no relevance. */
  533. UNIV_INLINE
  534. void
  535. dict_table_release(
  536. /*===============*/
  537. dict_table_t* table) /* in: table to be released */
  538. {
  539. mutex_enter(&(dict_sys->mutex));
  540. table->mem_fix--;
  541. mutex_exit(&(dict_sys->mutex));
  542. }
  543. /**************************************************************************
  544. Returns an index object. */
  545. UNIV_INLINE
  546. dict_index_t*
  547. dict_table_get_index(
  548. /*=================*/
  549. /* out: index, NULL if does not exist */
  550. dict_table_t* table, /* in: table */
  551. char* name) /* in: index name */
  552. {
  553. dict_index_t* index = NULL;
  554. mutex_enter(&(dict_sys->mutex));
  555. index = dict_table_get_first_index(table);
  556. while (index != NULL) {
  557. if (ut_strcmp(name, index->name) == 0) {
  558. break;
  559. }
  560. index = dict_table_get_next_index(index);
  561. }
  562. mutex_exit(&(dict_sys->mutex));
  563. return(index);
  564. }
  565. /***********************************************************************
  566. Checks if a table which is a mixed cluster member owns a record. */
  567. UNIV_INLINE
  568. ibool
  569. dict_is_mixed_table_rec(
  570. /*====================*/
  571. /* out: TRUE if the record belongs to this
  572. table */
  573. dict_table_t* table, /* in: table in a mixed cluster */
  574. rec_t* rec) /* in: user record in the clustered index */
  575. {
  576. byte* mix_id_field;
  577. ulint len;
  578. mix_id_field = rec_get_nth_field(rec, table->mix_len, &len);
  579. if ((len != table->mix_id_len)
  580.     || (0 != ut_memcmp(table->mix_id_buf, mix_id_field, len))) {
  581. return(FALSE);
  582. }
  583. return(TRUE);
  584. }