1 /*****************************************************************************
2 
3 Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
4 
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License, version 2.0,
7 as published by the Free Software Foundation.
8 
9 This program is also distributed with certain software (including
10 but not limited to OpenSSL) that is licensed under separate terms,
11 as designated in a particular file or component or in included license
12 documentation.  The authors of MySQL hereby grant you an additional
13 permission to link the program and your derivative works with the
14 separately licensed software that they have included with MySQL.
15 
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 GNU General Public License, version 2.0, for more details.
20 
21 You should have received a copy of the GNU General Public License along with
22 this program; if not, write to the Free Software Foundation, Inc.,
23 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
24 
25 *****************************************************************************/
26 
27 /**************************************************//**
28 @file include/dict0load.h
29 Loads to the memory cache database object definitions
30 from dictionary tables
31 
32 Created 4/24/1996 Heikki Tuuri
33 *******************************************************/
34 
35 #ifndef dict0load_h
36 #define dict0load_h
37 
38 #include "univ.i"
39 #include "dict0types.h"
40 #include "trx0types.h"
41 #include "ut0byte.h"
42 #include "mem0mem.h"
43 #include "btr0types.h"
44 
45 /** enum that defines all system table IDs. @see SYSTEM_TABLE_NAME[] */
46 enum dict_system_id_t {
47 	SYS_TABLES = 0,
48 	SYS_INDEXES,
49 	SYS_COLUMNS,
50 	SYS_FIELDS,
51 	SYS_FOREIGN,
52 	SYS_FOREIGN_COLS,
53 	SYS_TABLESPACES,
54 	SYS_DATAFILES,
55 
56 	/* This must be last item. Defines the number of system tables. */
57 	SYS_NUM_SYSTEM_TABLES
58 };
59 
60 /** Status bit for dict_process_sys_tables_rec_and_mtr_commit() */
61 enum dict_table_info_t {
62 	DICT_TABLE_LOAD_FROM_RECORD = 0,/*!< Directly populate a dict_table_t
63 					structure with information from
64 					a SYS_TABLES record */
65 	DICT_TABLE_LOAD_FROM_CACHE = 1	/*!< Check first whether dict_table_t
66 					is in the cache, if so, return it */
67 };
68 
69 /** Check type for dict_check_tablespaces_and_store_max_id() */
70 enum dict_check_t {
71 	/** No user tablespaces have been opened
72 	(no crash recovery, no transactions recovered). */
73 	DICT_CHECK_NONE_LOADED = 0,
74 	/** Some user tablespaces may have been opened
75 	(no crash recovery; recovered table locks for transactions). */
76 	DICT_CHECK_SOME_LOADED,
77 	/** All user tablespaces have been opened (crash recovery). */
78 	DICT_CHECK_ALL_LOADED
79 };
80 
81 /********************************************************************//**
82 In a crash recovery we already have all the tablespace objects created.
83 This function compares the space id information in the InnoDB data dictionary
84 to what we already read with fil_load_single_table_tablespaces().
85 
86 In a normal startup, we create the tablespace objects for every table in
87 InnoDB's data dictionary, if the corresponding .ibd file exists.
88 We also scan the biggest space id, and store it to fil_system. */
89 UNIV_INTERN
90 void
91 dict_check_tablespaces_and_store_max_id(
92 /*====================================*/
93 	dict_check_t	dict_check);	/*!< in: how to check */
94 /********************************************************************//**
95 Finds the first table name in the given database.
96 @return own: table name, NULL if does not exist; the caller must free
97 the memory in the string! */
98 UNIV_INTERN
99 char*
100 dict_get_first_table_name_in_db(
101 /*============================*/
102 	const char*	name);	/*!< in: database name which ends to '/' */
103 
104 /********************************************************************//**
105 Loads a table definition from a SYS_TABLES record to dict_table_t.
106 Does not load any columns or indexes.
107 @return error message, or NULL on success */
108 UNIV_INTERN
109 const char*
110 dict_load_table_low(
111 /*================*/
112 	const char*	name,		/*!< in: table name */
113 	const rec_t*	rec,		/*!< in: SYS_TABLES record */
114 	dict_table_t**	table);		/*!< out,own: table, or NULL */
115 /********************************************************************//**
116 Loads a table column definition from a SYS_COLUMNS record to
117 dict_table_t.
118 @return error message, or NULL on success */
119 UNIV_INTERN
120 const char*
121 dict_load_column_low(
122 /*=================*/
123 	dict_table_t*	table,		/*!< in/out: table, could be NULL
124 					if we just populate a dict_column_t
125 					struct with information from
126 					a SYS_COLUMNS record */
127 	mem_heap_t*	heap,		/*!< in/out: memory heap
128 					for temporary storage */
129 	dict_col_t*	column,		/*!< out: dict_column_t to fill,
130 					or NULL if table != NULL */
131 	table_id_t*	table_id,	/*!< out: table id */
132 	const char**	col_name,	/*!< out: column name */
133 	const rec_t*	rec);		/*!< in: SYS_COLUMNS record */
134 /********************************************************************//**
135 Loads an index definition from a SYS_INDEXES record to dict_index_t.
136 If allocate=TRUE, we will create a dict_index_t structure and fill it
137 accordingly. If allocated=FALSE, the dict_index_t will be supplied by
138 the caller and filled with information read from the record.  @return
139 error message, or NULL on success */
140 UNIV_INTERN
141 const char*
142 dict_load_index_low(
143 /*================*/
144 	byte*		table_id,	/*!< in/out: table id (8 bytes),
145 					an "in" value if allocate=TRUE
146 					and "out" when allocate=FALSE */
147 	const char*	table_name,	/*!< in: table name */
148 	mem_heap_t*	heap,		/*!< in/out: temporary memory heap */
149 	const rec_t*	rec,		/*!< in: SYS_INDEXES record */
150 	ibool		allocate,	/*!< in: TRUE=allocate *index,
151 					FALSE=fill in a pre-allocated
152 					*index */
153 	dict_index_t**	index);		/*!< out,own: index, or NULL */
154 /********************************************************************//**
155 Loads an index field definition from a SYS_FIELDS record to
156 dict_index_t.
157 @return error message, or NULL on success */
158 UNIV_INTERN
159 const char*
160 dict_load_field_low(
161 /*================*/
162 	byte*		index_id,	/*!< in/out: index id (8 bytes)
163 					an "in" value if index != NULL
164 					and "out" if index == NULL */
165 	dict_index_t*	index,		/*!< in/out: index, could be NULL
166 					if we just populate a dict_field_t
167 					struct with information from
168 					a SYS_FIELDS record */
169 	dict_field_t*	sys_field,	/*!< out: dict_field_t to be
170 					filled */
171 	ulint*		pos,		/*!< out: Field position */
172 	byte*		last_index_id,	/*!< in: last index id */
173 	mem_heap_t*	heap,		/*!< in/out: memory heap
174 					for temporary storage */
175 	const rec_t*	rec);		/*!< in: SYS_FIELDS record */
176 /********************************************************************//**
177 Using the table->heap, copy the null-terminated filepath into
178 table->data_dir_path and put a null byte before the extension.
179 This allows SHOW CREATE TABLE to return the correct DATA DIRECTORY path.
180 Make this data directory path only if it has not yet been saved. */
181 UNIV_INTERN
182 void
183 dict_save_data_dir_path(
184 /*====================*/
185 	dict_table_t*	table,		/*!< in/out: table */
186 	char*		filepath);	/*!< in: filepath of tablespace */
187 /*****************************************************************//**
188 Make sure the data_file_name is saved in dict_table_t if needed. Try to
189 read it from the file dictionary first, then from SYS_DATAFILES. */
190 UNIV_INTERN
191 void
192 dict_get_and_save_data_dir_path(
193 /*============================*/
194 	dict_table_t*	table,		/*!< in/out: table */
195 	bool		dict_mutex_own);	/*!< in: true if dict_sys->mutex
196 					is owned already */
197 /********************************************************************//**
198 Loads a table definition and also all its index definitions, and also
199 the cluster definition if the table is a member in a cluster. Also loads
200 all foreign key constraints where the foreign key is in the table or where
201 a foreign key references columns in this table.
202 @return table, NULL if does not exist; if the table is stored in an
203 .ibd file, but the file does not exist, then we set the
204 ibd_file_missing flag TRUE in the table object we return */
205 UNIV_INTERN
206 dict_table_t*
207 dict_load_table(
208 /*============*/
209 	const char*	name,	/*!< in: table name in the
210 				databasename/tablename format */
211 	ibool		cached,	/*!< in: TRUE=add to cache, FALSE=do not */
212 	dict_err_ignore_t ignore_err);
213 				/*!< in: error to be ignored when loading
214 				table and its indexes' definition */
215 /***********************************************************************//**
216 Loads a table object based on the table id.
217 @return	table; NULL if table does not exist */
218 UNIV_INTERN
219 dict_table_t*
220 dict_load_table_on_id(
221 /*==================*/
222 	table_id_t		table_id,	/*!< in: table id */
223 	dict_err_ignore_t	ignore_err);	/*!< in: errors to ignore
224 						when loading the table */
225 /********************************************************************//**
226 This function is called when the database is booted.
227 Loads system table index definitions except for the clustered index which
228 is added to the dictionary cache at booting before calling this function. */
229 UNIV_INTERN
230 void
231 dict_load_sys_table(
232 /*================*/
233 	dict_table_t*	table);	/*!< in: system table */
234 /***********************************************************************//**
235 Loads foreign key constraints where the table is either the foreign key
236 holder or where the table is referenced by a foreign key. Adds these
237 constraints to the data dictionary. Note that we know that the dictionary
238 cache already contains all constraints where the other relevant table is
239 already in the dictionary cache.
240 @return	DB_SUCCESS or error code */
241 UNIV_INTERN
242 dberr_t
243 dict_load_foreigns(
244 /*===============*/
245 	const char*		table_name,	/*!< in: table name */
246 	const char**		col_names,	/*!< in: column names, or NULL
247 						to use table->col_names */
248 	bool			check_recursive,/*!< in: Whether to check
249 						recursive load of tables
250 						chained by FK */
251 	bool			check_charsets,	/*!< in: whether to check
252 						charset compatibility */
253 	dict_err_ignore_t	ignore_err)	/*!< in: error to be ignored */
254 	MY_ATTRIBUTE((nonnull(1), warn_unused_result));
255 /********************************************************************//**
256 Prints to the standard output information on all tables found in the data
257 dictionary system table. */
258 UNIV_INTERN
259 void
260 dict_print(void);
261 /*============*/
262 
263 /********************************************************************//**
264 This function opens a system table, and return the first record.
265 @return	first record of the system table */
266 UNIV_INTERN
267 const rec_t*
268 dict_startscan_system(
269 /*==================*/
270 	btr_pcur_t*	pcur,		/*!< out: persistent cursor to
271 					the record */
272 	mtr_t*		mtr,		/*!< in: the mini-transaction */
273 	dict_system_id_t system_id);	/*!< in: which system table to open */
274 /********************************************************************//**
275 This function get the next system table record as we scan the table.
276 @return	the record if found, NULL if end of scan. */
277 UNIV_INTERN
278 const rec_t*
279 dict_getnext_system(
280 /*================*/
281 	btr_pcur_t*	pcur,		/*!< in/out: persistent cursor
282 					to the record */
283 	mtr_t*		mtr);		/*!< in: the mini-transaction */
284 /********************************************************************//**
285 This function processes one SYS_TABLES record and populate the dict_table_t
286 struct for the table. Extracted out of dict_print() to be used by
287 both monitor table output and information schema innodb_sys_tables output.
288 @return error message, or NULL on success */
289 UNIV_INTERN
290 const char*
291 dict_process_sys_tables_rec_and_mtr_commit(
292 /*=======================================*/
293 	mem_heap_t*	heap,		/*!< in: temporary memory heap */
294 	const rec_t*	rec,		/*!< in: SYS_TABLES record */
295 	dict_table_t**	table,		/*!< out: dict_table_t to fill */
296 	dict_table_info_t status,	/*!< in: status bit controls
297 					options such as whether we shall
298 					look for dict_table_t from cache
299 					first */
300 	mtr_t*		mtr);		/*!< in/out: mini-transaction,
301 					will be committed */
302 /********************************************************************//**
303 This function parses a SYS_INDEXES record and populate a dict_index_t
304 structure with the information from the record. For detail information
305 about SYS_INDEXES fields, please refer to dict_boot() function.
306 @return error message, or NULL on success */
307 UNIV_INTERN
308 const char*
309 dict_process_sys_indexes_rec(
310 /*=========================*/
311 	mem_heap_t*	heap,		/*!< in/out: heap memory */
312 	const rec_t*	rec,		/*!< in: current SYS_INDEXES rec */
313 	dict_index_t*	index,		/*!< out: dict_index_t to be
314 					filled */
315 	table_id_t*	table_id);	/*!< out: table id */
316 /********************************************************************//**
317 This function parses a SYS_COLUMNS record and populate a dict_column_t
318 structure with the information from the record.
319 @return error message, or NULL on success */
320 UNIV_INTERN
321 const char*
322 dict_process_sys_columns_rec(
323 /*=========================*/
324 	mem_heap_t*	heap,		/*!< in/out: heap memory */
325 	const rec_t*	rec,		/*!< in: current SYS_COLUMNS rec */
326 	dict_col_t*	column,		/*!< out: dict_col_t to be filled */
327 	table_id_t*	table_id,	/*!< out: table id */
328 	const char**	col_name);	/*!< out: column name */
329 /********************************************************************//**
330 This function parses a SYS_FIELDS record and populate a dict_field_t
331 structure with the information from the record.
332 @return error message, or NULL on success */
333 UNIV_INTERN
334 const char*
335 dict_process_sys_fields_rec(
336 /*========================*/
337 	mem_heap_t*	heap,		/*!< in/out: heap memory */
338 	const rec_t*	rec,		/*!< in: current SYS_FIELDS rec */
339 	dict_field_t*	sys_field,	/*!< out: dict_field_t to be
340 					filled */
341 	ulint*		pos,		/*!< out: Field position */
342 	index_id_t*	index_id,	/*!< out: current index id */
343 	index_id_t	last_id);	/*!< in: previous index id */
344 /********************************************************************//**
345 This function parses a SYS_FOREIGN record and populate a dict_foreign_t
346 structure with the information from the record. For detail information
347 about SYS_FOREIGN fields, please refer to dict_load_foreign() function
348 @return error message, or NULL on success */
349 UNIV_INTERN
350 const char*
351 dict_process_sys_foreign_rec(
352 /*=========================*/
353 	mem_heap_t*	heap,		/*!< in/out: heap memory */
354 	const rec_t*	rec,		/*!< in: current SYS_FOREIGN rec */
355 	dict_foreign_t*	foreign);	/*!< out: dict_foreign_t to be
356 					filled */
357 /********************************************************************//**
358 This function parses a SYS_FOREIGN_COLS record and extract necessary
359 information from the record and return to caller.
360 @return error message, or NULL on success */
361 UNIV_INTERN
362 const char*
363 dict_process_sys_foreign_col_rec(
364 /*=============================*/
365 	mem_heap_t*	heap,		/*!< in/out: heap memory */
366 	const rec_t*	rec,		/*!< in: current SYS_FOREIGN_COLS rec */
367 	const char**	name,		/*!< out: foreign key constraint name */
368 	const char**	for_col_name,	/*!< out: referencing column name */
369 	const char**	ref_col_name,	/*!< out: referenced column name
370 					in referenced table */
371 	ulint*		pos);		/*!< out: column position */
372 /********************************************************************//**
373 This function parses a SYS_TABLESPACES record, extracts necessary
374 information from the record and returns to caller.
375 @return error message, or NULL on success */
376 UNIV_INTERN
377 const char*
378 dict_process_sys_tablespaces(
379 /*=========================*/
380 	mem_heap_t*	heap,		/*!< in/out: heap memory */
381 	const rec_t*	rec,		/*!< in: current SYS_TABLESPACES rec */
382 	ulint*		space,		/*!< out: pace id */
383 	const char**	name,		/*!< out: tablespace name */
384 	ulint*		flags);		/*!< out: tablespace flags */
385 /********************************************************************//**
386 This function parses a SYS_DATAFILES record, extracts necessary
387 information from the record and returns to caller.
388 @return error message, or NULL on success */
389 UNIV_INTERN
390 const char*
391 dict_process_sys_datafiles(
392 /*=======================*/
393 	mem_heap_t*	heap,		/*!< in/out: heap memory */
394 	const rec_t*	rec,		/*!< in: current SYS_DATAFILES rec */
395 	ulint*		space,		/*!< out: pace id */
396 	const char**	path);		/*!< out: datafile path */
397 /********************************************************************//**
398 Get the filepath for a spaceid from SYS_DATAFILES. This function provides
399 a temporary heap which is used for the table lookup, but not for the path.
400 The caller must free the memory for the path returned. This function can
401 return NULL if the space ID is not found in SYS_DATAFILES, then the caller
402 will assume that the ibd file is in the normal datadir.
403 @return	own: A copy of the first datafile found in SYS_DATAFILES.PATH for
404 the given space ID. NULL if space ID is zero or not found. */
405 UNIV_INTERN
406 char*
407 dict_get_first_path(
408 /*================*/
409 	ulint		space,	/*!< in: space id */
410 	const char*	name);	/*!< in: tablespace name */
411 /********************************************************************//**
412 Update the record for space_id in SYS_TABLESPACES to this filepath.
413 @return	DB_SUCCESS if OK, dberr_t if the insert failed */
414 UNIV_INTERN
415 dberr_t
416 dict_update_filepath(
417 /*=================*/
418 	ulint		space_id,	/*!< in: space id */
419 	const char*	filepath);	/*!< in: filepath */
420 /********************************************************************//**
421 Insert records into SYS_TABLESPACES and SYS_DATAFILES.
422 @return	DB_SUCCESS if OK, dberr_t if the insert failed */
423 UNIV_INTERN
424 dberr_t
425 dict_insert_tablespace_and_filepath(
426 /*================================*/
427 	ulint		space,		/*!< in: space id */
428 	const char*	name,		/*!< in: talespace name */
429 	const char*	filepath,	/*!< in: filepath */
430 	ulint		fsp_flags);	/*!< in: tablespace flags */
431 
432 #ifndef UNIV_NONINL
433 #include "dict0load.ic"
434 #endif
435 
436 #endif
437