1/*****************************************************************************
2
3Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
4Copyright (c) 2017, 2018, MariaDB Corporation.
5
6This program is free software; you can redistribute it and/or modify it under
7the terms of the GNU General Public License as published by the Free Software
8Foundation; version 2 of the License.
9
10This program is distributed in the hope that it will be useful, but WITHOUT
11ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License along with
15this program; if not, write to the Free Software Foundation, Inc.,
1651 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
17
18*****************************************************************************/
19
20/**************************************************//**
21@file include/dict0load.h
22Loads to the memory cache database object definitions
23from dictionary tables
24
25Created 4/24/1996 Heikki Tuuri
26*******************************************************/
27
28#ifndef dict0load_h
29#define dict0load_h
30
31#include "univ.i"
32#include "dict0types.h"
33#include "trx0types.h"
34#include "ut0byte.h"
35#include "mem0mem.h"
36#include "btr0types.h"
37#include "ut0new.h"
38
39#include <deque>
40
41/** A stack of table names related through foreign key constraints */
42typedef std::deque<const char*, ut_allocator<const char*> > dict_names_t;
43
44/** enum that defines all system table IDs. @see SYSTEM_TABLE_NAME[] */
45enum dict_system_id_t {
46 SYS_TABLES = 0,
47 SYS_INDEXES,
48 SYS_COLUMNS,
49 SYS_FIELDS,
50 SYS_FOREIGN,
51 SYS_FOREIGN_COLS,
52 SYS_TABLESPACES,
53 SYS_DATAFILES,
54 SYS_VIRTUAL,
55
56 /* This must be last item. Defines the number of system tables. */
57 SYS_NUM_SYSTEM_TABLES
58};
59
60/** Check each tablespace found in the data dictionary.
61Look at each table defined in SYS_TABLES that has a space_id > 0.
62If the tablespace is not yet in the fil_system cache, look up the
63tablespace in SYS_DATAFILES to ensure the correct path.
64
65In a crash recovery we already have some tablespace objects created from
66processing the REDO log. Any other tablespace in SYS_TABLESPACES not
67previously used in recovery will be opened here. We will compare the
68space_id information in the data dictionary to what we find in the
69tablespace file. In addition, more validation will be done if recovery
70was needed and force_recovery is not set.
71
72We also scan the biggest space id, and store it to fil_system.
73@param[in] validate true if recovery was needed */
74void
75dict_check_tablespaces_and_store_max_id(
76 bool validate);
77
78/********************************************************************//**
79Finds the first table name in the given database.
80@return own: table name, NULL if does not exist; the caller must free
81the memory in the string! */
82char*
83dict_get_first_table_name_in_db(
84/*============================*/
85 const char* name); /*!< in: database name which ends to '/' */
86
87/** Get the first filepath from SYS_DATAFILES for a given space_id.
88@param[in] space_id Tablespace ID
89@return First filepath (caller must invoke ut_free() on it)
90@retval NULL if no SYS_DATAFILES entry was found. */
91char*
92dict_get_first_path(
93 ulint space_id);
94
95/** Make sure the data_file_name is saved in dict_table_t if needed.
96Try to read it from the fil_system first, then from SYS_DATAFILES.
97@param[in] table Table object
98@param[in] dict_mutex_own true if dict_sys->mutex is owned already */
99void
100dict_get_and_save_data_dir_path(
101 dict_table_t* table,
102 bool dict_mutex_own);
103
104/** Loads a table definition and also all its index definitions, and also
105the cluster definition if the table is a member in a cluster. Also loads
106all foreign key constraints where the foreign key is in the table or where
107a foreign key references columns in this table.
108@param[in] name Table name in the dbname/tablename format
109@param[in] cached true=add to cache, false=do not
110@param[in] ignore_err Error to be ignored when loading
111 table and its index definition
112@return table, NULL if does not exist; if the table is stored in an
113.ibd file, but the file does not exist, then we set the file_unreadable
114flag in the table object we return. */
115dict_table_t*
116dict_load_table(
117 const char* name,
118 bool cached,
119 dict_err_ignore_t ignore_err);
120
121/***********************************************************************//**
122Loads a table object based on the table id.
123@return table; NULL if table does not exist */
124dict_table_t*
125dict_load_table_on_id(
126/*==================*/
127 table_id_t table_id, /*!< in: table id */
128 dict_err_ignore_t ignore_err); /*!< in: errors to ignore
129 when loading the table */
130/********************************************************************//**
131This function is called when the database is booted.
132Loads system table index definitions except for the clustered index which
133is added to the dictionary cache at booting before calling this function. */
134void
135dict_load_sys_table(
136/*================*/
137 dict_table_t* table); /*!< in: system table */
138/***********************************************************************//**
139Loads foreign key constraints where the table is either the foreign key
140holder or where the table is referenced by a foreign key. Adds these
141constraints to the data dictionary.
142
143The foreign key constraint is loaded only if the referenced table is also
144in the dictionary cache. If the referenced table is not in dictionary
145cache, then it is added to the output parameter (fk_tables).
146
147@return DB_SUCCESS or error code */
148dberr_t
149dict_load_foreigns(
150/*===============*/
151 const char* table_name, /*!< in: table name */
152 const char** col_names, /*!< in: column names, or NULL
153 to use table->col_names */
154 bool check_recursive,/*!< in: Whether to check
155 recursive load of tables
156 chained by FK */
157 bool check_charsets, /*!< in: whether to check
158 charset compatibility */
159 dict_err_ignore_t ignore_err, /*!< in: error to be ignored */
160 dict_names_t& fk_tables) /*!< out: stack of table names
161 which must be loaded
162 subsequently to load all the
163 foreign key constraints. */
164 MY_ATTRIBUTE((nonnull(1), warn_unused_result));
165
166/********************************************************************//**
167This function opens a system table, and return the first record.
168@return first record of the system table */
169const rec_t*
170dict_startscan_system(
171/*==================*/
172 btr_pcur_t* pcur, /*!< out: persistent cursor to
173 the record */
174 mtr_t* mtr, /*!< in: the mini-transaction */
175 dict_system_id_t system_id); /*!< in: which system table to open */
176/********************************************************************//**
177This function get the next system table record as we scan the table.
178@return the record if found, NULL if end of scan. */
179const rec_t*
180dict_getnext_system(
181/*================*/
182 btr_pcur_t* pcur, /*!< in/out: persistent cursor
183 to the record */
184 mtr_t* mtr); /*!< in: the mini-transaction */
185/********************************************************************//**
186This function processes one SYS_TABLES record and populate the dict_table_t
187struct for the table.
188@return error message, or NULL on success */
189const char*
190dict_process_sys_tables_rec_and_mtr_commit(
191/*=======================================*/
192 mem_heap_t* heap, /*!< in: temporary memory heap */
193 const rec_t* rec, /*!< in: SYS_TABLES record */
194 dict_table_t** table, /*!< out: dict_table_t to fill */
195 bool cached, /*!< in: whether to load from cache */
196 mtr_t* mtr); /*!< in/out: mini-transaction,
197 will be committed */
198/********************************************************************//**
199This function parses a SYS_INDEXES record and populate a dict_index_t
200structure with the information from the record. For detail information
201about SYS_INDEXES fields, please refer to dict_boot() function.
202@return error message, or NULL on success */
203const char*
204dict_process_sys_indexes_rec(
205/*=========================*/
206 mem_heap_t* heap, /*!< in/out: heap memory */
207 const rec_t* rec, /*!< in: current SYS_INDEXES rec */
208 dict_index_t* index, /*!< out: dict_index_t to be
209 filled */
210 table_id_t* table_id); /*!< out: table id */
211/********************************************************************//**
212This function parses a SYS_COLUMNS record and populate a dict_column_t
213structure with the information from the record.
214@return error message, or NULL on success */
215const char*
216dict_process_sys_columns_rec(
217/*=========================*/
218 mem_heap_t* heap, /*!< in/out: heap memory */
219 const rec_t* rec, /*!< in: current SYS_COLUMNS rec */
220 dict_col_t* column, /*!< out: dict_col_t to be filled */
221 table_id_t* table_id, /*!< out: table id */
222 const char** col_name, /*!< out: column name */
223 ulint* nth_v_col); /*!< out: if virtual col, this is
224 records its sequence number */
225
226/** This function parses a SYS_VIRTUAL record and extract virtual column
227information
228@param[in,out] heap heap memory
229@param[in] rec current SYS_COLUMNS rec
230@param[in,out] table_id table id
231@param[in,out] pos virtual column position
232@param[in,out] base_pos base column position
233@return error message, or NULL on success */
234const char*
235dict_process_sys_virtual_rec(
236 const rec_t* rec,
237 table_id_t* table_id,
238 ulint* pos,
239 ulint* base_pos);
240/********************************************************************//**
241This function parses a SYS_FIELDS record and populate a dict_field_t
242structure with the information from the record.
243@return error message, or NULL on success */
244const char*
245dict_process_sys_fields_rec(
246/*========================*/
247 mem_heap_t* heap, /*!< in/out: heap memory */
248 const rec_t* rec, /*!< in: current SYS_FIELDS rec */
249 dict_field_t* sys_field, /*!< out: dict_field_t to be
250 filled */
251 ulint* pos, /*!< out: Field position */
252 index_id_t* index_id, /*!< out: current index id */
253 index_id_t last_id); /*!< in: previous index id */
254/********************************************************************//**
255This function parses a SYS_FOREIGN record and populate a dict_foreign_t
256structure with the information from the record. For detail information
257about SYS_FOREIGN fields, please refer to dict_load_foreign() function
258@return error message, or NULL on success */
259const char*
260dict_process_sys_foreign_rec(
261/*=========================*/
262 mem_heap_t* heap, /*!< in/out: heap memory */
263 const rec_t* rec, /*!< in: current SYS_FOREIGN rec */
264 dict_foreign_t* foreign); /*!< out: dict_foreign_t to be
265 filled */
266/********************************************************************//**
267This function parses a SYS_FOREIGN_COLS record and extract necessary
268information from the record and return to caller.
269@return error message, or NULL on success */
270const char*
271dict_process_sys_foreign_col_rec(
272/*=============================*/
273 mem_heap_t* heap, /*!< in/out: heap memory */
274 const rec_t* rec, /*!< in: current SYS_FOREIGN_COLS rec */
275 const char** name, /*!< out: foreign key constraint name */
276 const char** for_col_name, /*!< out: referencing column name */
277 const char** ref_col_name, /*!< out: referenced column name
278 in referenced table */
279 ulint* pos); /*!< out: column position */
280/********************************************************************//**
281This function parses a SYS_TABLESPACES record, extracts necessary
282information from the record and returns to caller.
283@return error message, or NULL on success */
284const char*
285dict_process_sys_tablespaces(
286/*=========================*/
287 mem_heap_t* heap, /*!< in/out: heap memory */
288 const rec_t* rec, /*!< in: current SYS_TABLESPACES rec */
289 ulint* space, /*!< out: pace id */
290 const char** name, /*!< out: tablespace name */
291 ulint* flags); /*!< out: tablespace flags */
292/********************************************************************//**
293This function parses a SYS_DATAFILES record, extracts necessary
294information from the record and returns to caller.
295@return error message, or NULL on success */
296const char*
297dict_process_sys_datafiles(
298/*=======================*/
299 mem_heap_t* heap, /*!< in/out: heap memory */
300 const rec_t* rec, /*!< in: current SYS_DATAFILES rec */
301 ulint* space, /*!< out: pace id */
302 const char** path); /*!< out: datafile path */
303
304/** Update the record for space_id in SYS_TABLESPACES to this filepath.
305@param[in] space_id Tablespace ID
306@param[in] filepath Tablespace filepath
307@return DB_SUCCESS if OK, dberr_t if the insert failed */
308dberr_t
309dict_update_filepath(
310 ulint space_id,
311 const char* filepath);
312
313/** Replace records in SYS_TABLESPACES and SYS_DATAFILES associated with
314the given space_id using an independent transaction.
315@param[in] space_id Tablespace ID
316@param[in] name Tablespace name
317@param[in] filepath First filepath
318@param[in] fsp_flags Tablespace flags
319@return DB_SUCCESS if OK, dberr_t if the insert failed */
320dberr_t
321dict_replace_tablespace_and_filepath(
322 ulint space_id,
323 const char* name,
324 const char* filepath,
325 ulint fsp_flags);
326
327#endif
328