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

MySQL数据库

开发平台:

Visual C++

  1. /******************************************************
  2. Database object creation
  3. (c) 1996 Innobase Oy
  4. Created 1/8/1996 Heikki Tuuri
  5. *******************************************************/
  6. #include "dict0crea.h"
  7. #ifdef UNIV_NONINL
  8. #include "dict0crea.ic"
  9. #endif
  10. #include "btr0pcur.h"
  11. #include "btr0btr.h"
  12. #include "page0page.h"
  13. #include "mach0data.h"
  14. #include "dict0boot.h"
  15. #include "que0que.h"
  16. #include "row0ins.h"
  17. #include "pars0pars.h"
  18. /*********************************************************************
  19. Based on a table object, this function builds the entry to be inserted
  20. in the SYS_TABLES system table. */
  21. static
  22. dtuple_t*
  23. dict_create_sys_tables_tuple(
  24. /*=========================*/
  25. /* out: the tuple which should be inserted */
  26. dict_table_t* table,  /* in: table */
  27. mem_heap_t* heap); /* in: memory heap from which the memory for
  28. the built tuple is allocated */
  29. /*********************************************************************
  30. Based on a table object, this function builds the entry to be inserted
  31. in the SYS_COLUMNS system table. */
  32. static
  33. dtuple_t*
  34. dict_create_sys_columns_tuple(
  35. /*==========================*/
  36. /* out: the tuple which should be inserted */
  37. dict_table_t* table,  /* in: table */
  38. ulint i, /* in: column number */
  39. mem_heap_t* heap); /* in: memory heap from which the memory for
  40. the built tuple is allocated */
  41. /*********************************************************************
  42. Based on an index object, this function builds the entry to be inserted
  43. in the SYS_INDEXES system table. */
  44. static
  45. dtuple_t*
  46. dict_create_sys_indexes_tuple(
  47. /*==========================*/
  48. /* out: the tuple which should be inserted */
  49. dict_index_t* index,  /* in: index */
  50. mem_heap_t* heap, /* in: memory heap from which the memory for
  51. the built tuple is allocated */
  52. trx_t* trx); /* in: transaction handle */
  53. /*********************************************************************
  54. Based on an index object, this function builds the entry to be inserted
  55. in the SYS_FIELDS system table. */
  56. static
  57. dtuple_t*
  58. dict_create_sys_fields_tuple(
  59. /*=========================*/
  60. /* out: the tuple which should be inserted */
  61. dict_index_t* index,  /* in: index */
  62. ulint i, /* in: field number */
  63. mem_heap_t* heap); /* in: memory heap from which the memory for
  64. the built tuple is allocated */
  65. /*********************************************************************
  66. Creates the tuple with which the index entry is searched for
  67. writing the index tree root page number, if such a tree is created. */
  68. static
  69. dtuple_t*
  70. dict_create_search_tuple(
  71. /*=====================*/
  72. /* out: the tuple for search */
  73. dtuple_t* tuple, /* in: the tuple inserted in the SYS_INDEXES
  74. table */
  75. mem_heap_t* heap); /* in: memory heap from which the memory for
  76. the built tuple is allocated */
  77. /*********************************************************************
  78. Based on a table object, this function builds the entry to be inserted
  79. in the SYS_TABLES system table. */
  80. static
  81. dtuple_t*
  82. dict_create_sys_tables_tuple(
  83. /*=========================*/
  84. /* out: the tuple which should be inserted */
  85. dict_table_t* table,  /* in: table */
  86. mem_heap_t* heap) /* in: memory heap from which the memory for
  87. the built tuple is allocated */
  88. {
  89. dict_table_t* sys_tables;
  90. dtuple_t* entry;
  91. dfield_t* dfield;
  92. byte* ptr;
  93. ut_ad(table && heap);
  94. sys_tables = dict_sys->sys_tables;
  95. entry = dtuple_create(heap, 8 + DATA_N_SYS_COLS);
  96. /* 0: NAME -----------------------------*/
  97. dfield = dtuple_get_nth_field(entry, 0);
  98. dfield_set_data(dfield, table->name, ut_strlen(table->name));
  99. /* 3: ID -------------------------------*/
  100. dfield = dtuple_get_nth_field(entry, 1);
  101. ptr = mem_heap_alloc(heap, 8);
  102. mach_write_to_8(ptr, table->id);
  103. dfield_set_data(dfield, ptr, 8);
  104. /* 4: N_COLS ---------------------------*/
  105. dfield = dtuple_get_nth_field(entry, 2);
  106. ptr = mem_heap_alloc(heap, 4);
  107. mach_write_to_4(ptr, table->n_def);
  108. dfield_set_data(dfield, ptr, 4);
  109. /* 5: TYPE -----------------------------*/
  110. dfield = dtuple_get_nth_field(entry, 3);
  111. ptr = mem_heap_alloc(heap, 4);
  112. mach_write_to_4(ptr, table->type);
  113. dfield_set_data(dfield, ptr, 4);
  114. /* 6: MIX_ID ---------------------------*/
  115. dfield = dtuple_get_nth_field(entry, 4);
  116. ptr = mem_heap_alloc(heap, 8);
  117. mach_write_to_8(ptr, table->mix_id);
  118. dfield_set_data(dfield, ptr, 8);
  119. /* 7: MIX_LEN --------------------------*/
  120. dfield = dtuple_get_nth_field(entry, 5);
  121. ptr = mem_heap_alloc(heap, 4);
  122. mach_write_to_4(ptr, table->mix_len);
  123. dfield_set_data(dfield, ptr, 4);
  124. /* 8: CLUSTER_NAME ---------------------*/
  125. dfield = dtuple_get_nth_field(entry, 6);
  126.   if (table->type == DICT_TABLE_CLUSTER_MEMBER) {
  127. dfield_set_data(dfield, table->cluster_name,
  128. ut_strlen(table->cluster_name));
  129. } else {
  130. dfield_set_data(dfield, NULL, UNIV_SQL_NULL);
  131. }
  132. /* 9: SPACE ----------------------------*/
  133. dfield = dtuple_get_nth_field(entry, 7);
  134. ptr = mem_heap_alloc(heap, 4);
  135. mach_write_to_4(ptr, table->space);
  136. dfield_set_data(dfield, ptr, 4);
  137. /*----------------------------------*/
  138. dict_table_copy_types(entry, sys_tables);
  139. return(entry);
  140. }
  141. /*********************************************************************
  142. Based on a table object, this function builds the entry to be inserted
  143. in the SYS_COLUMNS system table. */
  144. static
  145. dtuple_t*
  146. dict_create_sys_columns_tuple(
  147. /*==========================*/
  148. /* out: the tuple which should be inserted */
  149. dict_table_t* table,  /* in: table */
  150. ulint i, /* in: column number */
  151. mem_heap_t* heap) /* in: memory heap from which the memory for
  152. the built tuple is allocated */
  153. {
  154. dict_table_t* sys_columns;
  155. dtuple_t* entry;
  156. dict_col_t* column;
  157. dfield_t* dfield;
  158. byte* ptr;
  159. ut_ad(table && heap);
  160. column = dict_table_get_nth_col(table, i);
  161. sys_columns = dict_sys->sys_columns;
  162. entry = dtuple_create(heap, 7 + DATA_N_SYS_COLS);
  163. /* 0: TABLE_ID -----------------------*/
  164. dfield = dtuple_get_nth_field(entry, 0);
  165. ptr = mem_heap_alloc(heap, 8);
  166. mach_write_to_8(ptr, table->id);
  167. dfield_set_data(dfield, ptr, 8);
  168. /* 1: POS ----------------------------*/
  169. dfield = dtuple_get_nth_field(entry, 1);
  170. ptr = mem_heap_alloc(heap, 4);
  171. mach_write_to_4(ptr, i);
  172. dfield_set_data(dfield, ptr, 4);
  173. /* 4: NAME ---------------------------*/
  174. dfield = dtuple_get_nth_field(entry, 2);
  175. dfield_set_data(dfield, column->name, ut_strlen(column->name));
  176. /* 5: MTYPE --------------------------*/
  177. dfield = dtuple_get_nth_field(entry, 3);
  178. ptr = mem_heap_alloc(heap, 4);
  179. mach_write_to_4(ptr, (column->type).mtype);
  180. dfield_set_data(dfield, ptr, 4);
  181. /* 6: PRTYPE -------------------------*/
  182. dfield = dtuple_get_nth_field(entry, 4);
  183. ptr = mem_heap_alloc(heap, 4);
  184. mach_write_to_4(ptr, (column->type).prtype);
  185. dfield_set_data(dfield, ptr, 4);
  186. /* 7: LEN ----------------------------*/
  187. dfield = dtuple_get_nth_field(entry, 5);
  188. ptr = mem_heap_alloc(heap, 4);
  189. mach_write_to_4(ptr, (column->type).len);
  190. dfield_set_data(dfield, ptr, 4);
  191. /* 8: PREC ---------------------------*/
  192. dfield = dtuple_get_nth_field(entry, 6);
  193. ptr = mem_heap_alloc(heap, 4);
  194. mach_write_to_4(ptr, (column->type).prec);
  195. dfield_set_data(dfield, ptr, 4);
  196. /*---------------------------------*/
  197. dict_table_copy_types(entry, sys_columns);
  198. return(entry);
  199. }
  200. /*******************************************************************
  201. Builds a table definition to insert. */
  202. static
  203. ulint
  204. dict_build_table_def_step(
  205. /*======================*/
  206. /* out: DB_SUCCESS or error code */
  207. que_thr_t* thr, /* in: query thread */
  208. tab_node_t* node) /* in: table create node */
  209. {
  210. dict_table_t* table;
  211. dict_table_t* cluster_table;
  212. dtuple_t* row;
  213. UT_NOT_USED(thr);
  214. ut_ad(mutex_own(&(dict_sys->mutex)));
  215. table = node->table;
  216. table->id = dict_hdr_get_new_id(DICT_HDR_TABLE_ID);
  217. thr_get_trx(thr)->table_id = table->id;
  218. if (table->type == DICT_TABLE_CLUSTER_MEMBER) {
  219. cluster_table = dict_table_get_low(table->cluster_name);
  220. if (cluster_table == NULL) {
  221. return(DB_CLUSTER_NOT_FOUND);
  222. }
  223. /* Inherit space and mix len from the cluster */
  224. table->space = cluster_table->space;
  225. table->mix_len = cluster_table->mix_len;
  226. table->mix_id = dict_hdr_get_new_id(DICT_HDR_MIX_ID);
  227. }
  228. row = dict_create_sys_tables_tuple(table, node->heap);
  229. ins_node_set_new_row(node->tab_def, row);
  230. return(DB_SUCCESS);
  231. }
  232. /*******************************************************************
  233. Builds a column definition to insert. */
  234. static
  235. ulint
  236. dict_build_col_def_step(
  237. /*====================*/
  238. /* out: DB_SUCCESS */
  239. tab_node_t* node) /* in: table create node */
  240. {
  241. dtuple_t* row;
  242. row = dict_create_sys_columns_tuple(node->table, node->col_no,
  243. node->heap);
  244. ins_node_set_new_row(node->col_def, row);
  245. return(DB_SUCCESS);
  246. }
  247. #ifdef notdefined
  248. /*************************************************************************
  249. Creates the single index for a cluster: it contains all the columns of
  250. the cluster definition in the order they were defined. */
  251. static
  252. void
  253. dict_create_index_for_cluster_step(
  254. /*===============================*/
  255. tab_node_t* node) /* in: table create node */
  256. {
  257. dict_index_t* index;
  258. ulint i;
  259. dict_col_t* col;
  260. index = dict_mem_index_create(table->name, "IND_DEFAULT_CLUSTERED",
  261. table->space, DICT_CLUSTERED,
  262. table->n_cols);
  263. for (i = 0; i < table->n_cols; i++) {
  264. col = dict_table_get_nth_col(table, i);
  265. dict_mem_index_add_field(index, col->name, 0);
  266. }
  267. (node->cluster)->index = index;
  268. }
  269. #endif
  270. /*********************************************************************
  271. Based on an index object, this function builds the entry to be inserted
  272. in the SYS_INDEXES system table. */
  273. static
  274. dtuple_t*
  275. dict_create_sys_indexes_tuple(
  276. /*==========================*/
  277. /* out: the tuple which should be inserted */
  278. dict_index_t* index,  /* in: index */
  279. mem_heap_t* heap, /* in: memory heap from which the memory for
  280. the built tuple is allocated */
  281. trx_t* trx) /* in: transaction handle */
  282. {
  283. dict_table_t* sys_indexes;
  284. dict_table_t* table;
  285. dtuple_t* entry;
  286. dfield_t* dfield;
  287. byte* ptr;
  288. UT_NOT_USED(trx);
  289. ut_ad(mutex_own(&(dict_sys->mutex)));
  290. ut_ad(index && heap);
  291. sys_indexes = dict_sys->sys_indexes;
  292. table = dict_table_get_low(index->table_name);
  293. entry = dtuple_create(heap, 7 + DATA_N_SYS_COLS);
  294. /* 0: TABLE_ID -----------------------*/
  295. dfield = dtuple_get_nth_field(entry, 0);
  296. ptr = mem_heap_alloc(heap, 8);
  297. mach_write_to_8(ptr, table->id);
  298. dfield_set_data(dfield, ptr, 8);
  299. /* 1: ID ----------------------------*/
  300. dfield = dtuple_get_nth_field(entry, 1);
  301. ptr = mem_heap_alloc(heap, 8);
  302. mach_write_to_8(ptr, index->id);
  303. dfield_set_data(dfield, ptr, 8);
  304. /* 4: NAME --------------------------*/
  305. dfield = dtuple_get_nth_field(entry, 2);
  306. dfield_set_data(dfield, index->name, ut_strlen(index->name));
  307. /* 5: N_FIELDS ----------------------*/
  308. dfield = dtuple_get_nth_field(entry, 3);
  309. ptr = mem_heap_alloc(heap, 4);
  310. mach_write_to_4(ptr, index->n_fields);
  311. dfield_set_data(dfield, ptr, 4);
  312. /* 6: TYPE --------------------------*/
  313. dfield = dtuple_get_nth_field(entry, 4);
  314. ptr = mem_heap_alloc(heap, 4);
  315. mach_write_to_4(ptr, index->type);
  316. dfield_set_data(dfield, ptr, 4);
  317. /* 7: SPACE --------------------------*/
  318. ut_a(DICT_SYS_INDEXES_SPACE_NO_FIELD == 7);
  319. dfield = dtuple_get_nth_field(entry, 5);
  320. ptr = mem_heap_alloc(heap, 4);
  321. mach_write_to_4(ptr, index->space);
  322. dfield_set_data(dfield, ptr, 4);
  323. /* 8: PAGE_NO --------------------------*/
  324. ut_a(DICT_SYS_INDEXES_PAGE_NO_FIELD == 8);
  325. dfield = dtuple_get_nth_field(entry, 6);
  326. ptr = mem_heap_alloc(heap, 4);
  327. mach_write_to_4(ptr, FIL_NULL);
  328. dfield_set_data(dfield, ptr, 4);
  329. /*--------------------------------*/
  330. dict_table_copy_types(entry, sys_indexes);
  331. return(entry);
  332. }
  333. /*********************************************************************
  334. Based on an index object, this function builds the entry to be inserted
  335. in the SYS_FIELDS system table. */
  336. static
  337. dtuple_t*
  338. dict_create_sys_fields_tuple(
  339. /*=========================*/
  340. /* out: the tuple which should be inserted */
  341. dict_index_t* index,  /* in: index */
  342. ulint i, /* in: field number */
  343. mem_heap_t* heap) /* in: memory heap from which the memory for
  344. the built tuple is allocated */
  345. {
  346. dict_table_t* sys_fields;
  347. dtuple_t* entry;
  348. dict_field_t* field;
  349. dfield_t* dfield;
  350. byte* ptr;
  351. ut_ad(index && heap);
  352. field = dict_index_get_nth_field(index, i);
  353. sys_fields = dict_sys->sys_fields;
  354. entry = dtuple_create(heap, 3 + DATA_N_SYS_COLS);
  355. /* 0: INDEX_ID -----------------------*/
  356. dfield = dtuple_get_nth_field(entry, 0);
  357. ptr = mem_heap_alloc(heap, 8);
  358. mach_write_to_8(ptr, index->id);
  359. dfield_set_data(dfield, ptr, 8);
  360. /* 1: POS ----------------------------*/
  361. dfield = dtuple_get_nth_field(entry, 1);
  362. ptr = mem_heap_alloc(heap, 4);
  363. mach_write_to_4(ptr, i);
  364. dfield_set_data(dfield, ptr, 4);
  365. /* 4: COL_NAME -------------------------*/
  366. dfield = dtuple_get_nth_field(entry, 2);
  367. dfield_set_data(dfield, field->name,
  368. ut_strlen(field->name));
  369. /*---------------------------------*/
  370. dict_table_copy_types(entry, sys_fields);
  371. return(entry);
  372. }
  373. /*********************************************************************
  374. Creates the tuple with which the index entry is searched for
  375. writing the index tree root page number, if such a tree is created. */
  376. static
  377. dtuple_t*
  378. dict_create_search_tuple(
  379. /*=====================*/
  380. /* out: the tuple for search */
  381. dtuple_t* tuple, /* in: the tuple inserted in the SYS_INDEXES
  382. table */
  383. mem_heap_t* heap) /* in: memory heap from which the memory for
  384. the built tuple is allocated */
  385. {
  386. dtuple_t* search_tuple;
  387. dfield_t* field1;
  388. dfield_t* field2;
  389. ut_ad(tuple && heap);
  390. search_tuple = dtuple_create(heap, 2);
  391. field1 = dtuple_get_nth_field(tuple, 0);
  392. field2 = dtuple_get_nth_field(search_tuple, 0);
  393. dfield_copy(field2, field1);
  394. field1 = dtuple_get_nth_field(tuple, 1);
  395. field2 = dtuple_get_nth_field(search_tuple, 1);
  396. dfield_copy(field2, field1);
  397. ut_ad(dtuple_validate(search_tuple));
  398. return(search_tuple);
  399. }
  400. /*******************************************************************
  401. Builds an index definition row to insert. */
  402. static
  403. ulint
  404. dict_build_index_def_step(
  405. /*======================*/
  406. /* out: DB_SUCCESS or error code */
  407. que_thr_t* thr, /* in: query thread */
  408. ind_node_t* node) /* in: index create node */
  409. {
  410. dict_table_t* table;
  411. dict_index_t* index;
  412. dtuple_t* row;
  413. UT_NOT_USED(thr);
  414. ut_ad(mutex_own(&(dict_sys->mutex)));
  415. index = node->index;
  416. table = dict_table_get_low(index->table_name);
  417. if (table == NULL) {
  418. return(DB_TABLE_NOT_FOUND);
  419. }
  420. thr_get_trx(thr)->table_id = table->id;
  421. node->table = table;
  422. ut_ad((UT_LIST_GET_LEN(table->indexes) > 0)
  423.       || (index->type & DICT_CLUSTERED));
  424. index->id = dict_hdr_get_new_id(DICT_HDR_INDEX_ID);
  425. if (index->type & DICT_CLUSTERED) {
  426. /* Inherit the space from the table */
  427. index->space = table->space;
  428. }
  429. index->page_no = FIL_NULL;
  430. row = dict_create_sys_indexes_tuple(index, node->heap,
  431. thr_get_trx(thr));
  432. node->ind_row = row;
  433. ins_node_set_new_row(node->ind_def, row);
  434. return(DB_SUCCESS);
  435. }
  436. /*******************************************************************
  437. Builds a field definition row to insert. */
  438. static
  439. ulint
  440. dict_build_field_def_step(
  441. /*======================*/
  442. /* out: DB_SUCCESS */
  443. ind_node_t* node) /* in: index create node */
  444. {
  445. dict_index_t* index;
  446. dtuple_t* row;
  447. index = node->index;
  448. row = dict_create_sys_fields_tuple(index, node->field_no, node->heap);
  449. ins_node_set_new_row(node->field_def, row);
  450. return(DB_SUCCESS);
  451. }
  452. /*******************************************************************
  453. Creates an index tree for the index if it is not a member of a cluster. */
  454. static
  455. ulint
  456. dict_create_index_tree_step(
  457. /*========================*/
  458. /* out: DB_SUCCESS or DB_OUT_OF_FILE_SPACE */
  459. que_thr_t* thr, /* in: query thread */
  460. ind_node_t* node) /* in: index create node */
  461. {
  462. dict_index_t* index;
  463. dict_table_t* sys_indexes;
  464. dict_table_t* table;
  465. dtuple_t* search_tuple;
  466. btr_pcur_t pcur;
  467. mtr_t mtr;
  468. ut_ad(mutex_own(&(dict_sys->mutex)));
  469. UT_NOT_USED(thr);
  470. index = node->index;
  471. table = node->table;
  472. sys_indexes = dict_sys->sys_indexes;
  473. if (index->type & DICT_CLUSTERED
  474. && table->type == DICT_TABLE_CLUSTER_MEMBER) {
  475. /* Do not create a new index tree: entries are put to the
  476. cluster tree */
  477. return(DB_SUCCESS);
  478. }
  479. /* Run a mini-transaction in which the index tree is allocated for
  480. the index and its root address is written to the index entry in
  481. sys_indexes */
  482. mtr_start(&mtr);
  483. search_tuple = dict_create_search_tuple(node->ind_row, node->heap);
  484.     
  485. btr_pcur_open(UT_LIST_GET_FIRST(sys_indexes->indexes),
  486. search_tuple, PAGE_CUR_L, BTR_MODIFY_LEAF,
  487. &pcur, &mtr);
  488. btr_pcur_move_to_next_user_rec(&pcur, &mtr);
  489. index->page_no = btr_create(index->type, index->space, index->id,
  490. &mtr);
  491. page_rec_write_index_page_no(btr_pcur_get_rec(&pcur),
  492. DICT_SYS_INDEXES_PAGE_NO_FIELD,
  493. index->page_no, &mtr);
  494. btr_pcur_close(&pcur);
  495. mtr_commit(&mtr);
  496. if (index->page_no == FIL_NULL) {
  497. return(DB_OUT_OF_FILE_SPACE);
  498. }
  499. return(DB_SUCCESS);
  500. }
  501. /***********************************************************************
  502. Drops the index tree associated with a row in SYS_INDEXES table. */
  503. void
  504. dict_drop_index_tree(
  505. /*=================*/
  506. rec_t* rec, /* in: record in the clustered index of SYS_INDEXES
  507. table */
  508. mtr_t* mtr) /* in: mtr having the latch on the record page */
  509. {
  510. ulint root_page_no;
  511. ulint space;
  512. byte* ptr;
  513. ulint len;
  514. ut_ad(mutex_own(&(dict_sys->mutex)));
  515. ptr = rec_get_nth_field(rec, DICT_SYS_INDEXES_PAGE_NO_FIELD, &len);
  516. ut_ad(len == 4);
  517. root_page_no = mtr_read_ulint(ptr, MLOG_4BYTES, mtr);
  518. if (root_page_no == FIL_NULL) {
  519. /* The tree has already been freed */
  520. return;
  521. }
  522. ptr = rec_get_nth_field(rec, DICT_SYS_INDEXES_SPACE_NO_FIELD, &len);
  523. ut_ad(len == 4);
  524. space = mtr_read_ulint(ptr, MLOG_4BYTES, mtr);
  525. /* We free all the pages but the root page first; this operation
  526. may span several mini-transactions */
  527. btr_free_but_not_root(space, root_page_no);
  528. /* Then we free the root page in the same mini-transaction where
  529. we write FIL_NULL to the appropriate field in the SYS_INDEXES
  530. record: this mini-transaction marks the B-tree totally freed */
  531. btr_free_root(space, root_page_no, mtr);
  532. page_rec_write_index_page_no(rec, DICT_SYS_INDEXES_PAGE_NO_FIELD,
  533. FIL_NULL, mtr);
  534. }
  535. #ifdef notdefined
  536. /*************************************************************************
  537. Creates the default clustered index for a table: the records are ordered
  538. by row id. */
  539. void
  540. dict_create_default_index(
  541. /*======================*/
  542. dict_table_t* table, /* in: table */
  543. trx_t* trx) /* in: transaction handle */
  544. {
  545. dict_index_t* index;
  546. index = dict_mem_index_create(table->name, "IND_DEFAULT_CLUSTERED",
  547. table->space, DICT_CLUSTERED, 0);
  548. dict_create_index(index, trx); 
  549. }
  550. #endif
  551. /*************************************************************************
  552. Creates a table create graph. */
  553. tab_node_t*
  554. tab_create_graph_create(
  555. /*====================*/
  556. /* out, own: table create node */
  557. dict_table_t* table, /* in: table to create, built as a memory data
  558. structure */
  559. mem_heap_t* heap) /* in: heap where created */
  560. {
  561. tab_node_t* node;
  562. node = mem_heap_alloc(heap, sizeof(tab_node_t));
  563. node->common.type = QUE_NODE_CREATE_TABLE;
  564. node->table = table;
  565. node->state = TABLE_BUILD_TABLE_DEF;
  566. node->heap = mem_heap_create(256);
  567. node->tab_def = ins_node_create(INS_DIRECT, dict_sys->sys_tables,
  568. heap); 
  569. node->tab_def->common.parent = node;
  570. node->col_def = ins_node_create(INS_DIRECT, dict_sys->sys_columns,
  571. heap);
  572. node->col_def->common.parent = node;
  573. node->commit_node = commit_node_create(heap);
  574. node->commit_node->common.parent = node;
  575. return(node);
  576. }
  577. /*************************************************************************
  578. Creates an index create graph. */
  579. ind_node_t*
  580. ind_create_graph_create(
  581. /*====================*/
  582. /* out, own: index create node */
  583. dict_index_t* index, /* in: index to create, built as a memory data
  584. structure */
  585. mem_heap_t* heap) /* in: heap where created */
  586. {
  587. ind_node_t* node;
  588. node = mem_heap_alloc(heap, sizeof(ind_node_t));
  589. node->common.type = QUE_NODE_CREATE_INDEX;
  590. node->index = index;
  591. node->state = INDEX_BUILD_INDEX_DEF;
  592. node->heap = mem_heap_create(256);
  593. node->ind_def = ins_node_create(INS_DIRECT,
  594. dict_sys->sys_indexes, heap); 
  595. node->ind_def->common.parent = node;
  596. node->field_def = ins_node_create(INS_DIRECT,
  597. dict_sys->sys_fields, heap);
  598. node->field_def->common.parent = node;
  599. node->commit_node = commit_node_create(heap);
  600. node->commit_node->common.parent = node;
  601. return(node);
  602. }
  603. /***************************************************************
  604. Creates a table. This is a high-level function used in SQL execution graphs. */
  605. que_thr_t*
  606. dict_create_table_step(
  607. /*===================*/
  608. /* out: query thread to run next or NULL */
  609. que_thr_t* thr) /* in: query thread */
  610. {
  611. tab_node_t* node;
  612. ulint err = DB_ERROR;
  613. trx_t* trx;
  614. ut_ad(thr);
  615. ut_ad(mutex_own(&(dict_sys->mutex)));
  616. trx = thr_get_trx(thr);
  617. node = thr->run_node;
  618. ut_ad(que_node_get_type(node) == QUE_NODE_CREATE_TABLE);
  619. if (thr->prev_node == que_node_get_parent(node)) {
  620. node->state = TABLE_BUILD_TABLE_DEF;
  621. }
  622. if (node->state == TABLE_BUILD_TABLE_DEF) {
  623. /* DO THE CHECKS OF THE CONSISTENCY CONSTRAINTS HERE */
  624. err = dict_build_table_def_step(thr, node);
  625. if (err != DB_SUCCESS) {
  626. goto function_exit;
  627. }
  628. node->state = TABLE_BUILD_COL_DEF;
  629. node->col_no = 0;
  630. thr->run_node = node->tab_def;
  631. return(thr);
  632. }
  633. if (node->state == TABLE_BUILD_COL_DEF) {
  634. if (node->col_no < (node->table)->n_def) {
  635. err = dict_build_col_def_step(node);
  636. if (err != DB_SUCCESS) {
  637. goto function_exit;
  638. }
  639. node->col_no++;
  640. thr->run_node = node->col_def;
  641. return(thr);
  642. } else {
  643. node->state = TABLE_COMMIT_WORK;
  644. }
  645. }
  646. if (node->state == TABLE_COMMIT_WORK) {
  647. /* Table was correctly defined: do NOT commit the transaction
  648. (CREATE TABLE does NOT do an implicit commit of the current
  649. transaction) */
  650. node->state = TABLE_ADD_TO_CACHE;
  651. /* thr->run_node = node->commit_node;
  652. return(thr); */
  653. }
  654. if (node->state == TABLE_ADD_TO_CACHE) {
  655. dict_table_add_to_cache(node->table);
  656. err = DB_SUCCESS;
  657. }
  658. function_exit:
  659. trx->error_state = err;
  660. if (err == DB_SUCCESS) {
  661. /* Ok: do nothing */
  662. } else if (err == DB_LOCK_WAIT) {
  663. return(NULL);
  664. } else {
  665. /* SQL error detected */
  666. return(NULL);
  667. }
  668. thr->run_node = que_node_get_parent(node);
  669. return(thr);
  670. /***************************************************************
  671. Creates an index. This is a high-level function used in SQL execution
  672. graphs. */
  673. que_thr_t*
  674. dict_create_index_step(
  675. /*===================*/
  676. /* out: query thread to run next or NULL */
  677. que_thr_t* thr) /* in: query thread */
  678. {
  679. ind_node_t* node;
  680. ibool success;
  681. ulint err = DB_ERROR;
  682. trx_t* trx;
  683. ut_ad(thr);
  684. ut_ad(mutex_own(&(dict_sys->mutex)));
  685. trx = thr_get_trx(thr);
  686. node = thr->run_node;
  687. ut_ad(que_node_get_type(node) == QUE_NODE_CREATE_INDEX);
  688. if (thr->prev_node == que_node_get_parent(node)) {
  689. node->state = INDEX_BUILD_INDEX_DEF;
  690. }
  691. if (node->state == INDEX_BUILD_INDEX_DEF) {
  692. /* DO THE CHECKS OF THE CONSISTENCY CONSTRAINTS HERE */
  693. err = dict_build_index_def_step(thr, node);
  694. if (err != DB_SUCCESS) {
  695. goto function_exit;
  696. }
  697. node->state = INDEX_BUILD_FIELD_DEF;
  698. node->field_no = 0;
  699. thr->run_node = node->ind_def;
  700. return(thr);
  701. }
  702. if (node->state == INDEX_BUILD_FIELD_DEF) {
  703. if (node->field_no < (node->index)->n_fields) {
  704. err = dict_build_field_def_step(node);
  705. if (err != DB_SUCCESS) {
  706. goto function_exit;
  707. }
  708. node->field_no++;
  709. thr->run_node = node->field_def;
  710. return(thr);
  711. } else {
  712. node->state = INDEX_CREATE_INDEX_TREE;
  713. }
  714. }
  715. if (node->state == INDEX_CREATE_INDEX_TREE) {
  716. err = dict_create_index_tree_step(thr, node);
  717. if (err != DB_SUCCESS) {
  718. goto function_exit;
  719. }
  720. node->state = INDEX_COMMIT_WORK;
  721. }
  722. if (node->state == INDEX_COMMIT_WORK) {
  723. /* Index was correctly defined: do NOT commit the transaction
  724. (CREATE INDEX does NOT currently do an implicit commit of
  725. the current transaction) */
  726. node->state = INDEX_ADD_TO_CACHE;
  727. /* thr->run_node = node->commit_node;
  728. return(thr); */
  729. }
  730. if (node->state == INDEX_ADD_TO_CACHE) {
  731. success = dict_index_add_to_cache(node->table, node->index);
  732. ut_a(success);
  733. err = DB_SUCCESS;
  734. }
  735. function_exit:
  736. trx->error_state = err;
  737. if (err == DB_SUCCESS) {
  738. /* Ok: do nothing */
  739. } else if (err == DB_LOCK_WAIT) {
  740. return(NULL);
  741. } else {
  742. /* SQL error detected */
  743. return(NULL);
  744. }
  745. thr->run_node = que_node_get_parent(node);
  746. return(thr);