1 /* Copyright (c) 2006, 2014, Oracle and/or its affiliates.
2    Copyright (c) 2011, 2017, MariaDB Corporation.
3 
4    This program is free software; you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation; version 2 of the License.
7 
8    This program is distributed in the hope that it will be useful,
9    but WITHOUT ANY WARRANTY; without even the implied warranty of
10    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11    GNU General Public License for more details.
12 
13    You should have received a copy of the GNU General Public License
14    along with this program; if not, write to the Free Software
15    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1335  USA */
16 
17 #ifndef SQL_TABLE_INCLUDED
18 #define SQL_TABLE_INCLUDED
19 
20 #include <my_sys.h>                             // pthread_mutex_t
21 #include "m_string.h"                           // LEX_CUSTRING
22 
23 class Alter_info;
24 class Alter_table_ctx;
25 class Column_definition;
26 class Create_field;
27 struct TABLE_LIST;
28 class THD;
29 struct TABLE;
30 struct handlerton;
31 class handler;
32 class String;
33 typedef struct st_ha_check_opt HA_CHECK_OPT;
34 struct HA_CREATE_INFO;
35 struct Table_specification_st;
36 typedef struct st_key KEY;
37 typedef struct st_key_cache KEY_CACHE;
38 typedef struct st_lock_param_type ALTER_PARTITION_PARAM_TYPE;
39 typedef struct st_order ORDER;
40 
41 enum ddl_log_entry_code
42 {
43   /*
44     DDL_LOG_EXECUTE_CODE:
45       This is a code that indicates that this is a log entry to
46       be executed, from this entry a linked list of log entries
47       can be found and executed.
48     DDL_LOG_ENTRY_CODE:
49       An entry to be executed in a linked list from an execute log
50       entry.
51     DDL_IGNORE_LOG_ENTRY_CODE:
52       An entry that is to be ignored
53   */
54   DDL_LOG_EXECUTE_CODE = 'e',
55   DDL_LOG_ENTRY_CODE = 'l',
56   DDL_IGNORE_LOG_ENTRY_CODE = 'i'
57 };
58 
59 enum ddl_log_action_code
60 {
61   /*
62     The type of action that a DDL_LOG_ENTRY_CODE entry is to
63     perform.
64     DDL_LOG_DELETE_ACTION:
65       Delete an entity
66     DDL_LOG_RENAME_ACTION:
67       Rename an entity
68     DDL_LOG_REPLACE_ACTION:
69       Rename an entity after removing the previous entry with the
70       new name, that is replace this entry.
71     DDL_LOG_EXCHANGE_ACTION:
72       Exchange two entities by renaming them a -> tmp, b -> a, tmp -> b.
73   */
74   DDL_LOG_DELETE_ACTION = 'd',
75   DDL_LOG_RENAME_ACTION = 'r',
76   DDL_LOG_REPLACE_ACTION = 's',
77   DDL_LOG_EXCHANGE_ACTION = 'e'
78 };
79 
80 enum enum_ddl_log_exchange_phase {
81   EXCH_PHASE_NAME_TO_TEMP= 0,
82   EXCH_PHASE_FROM_TO_NAME= 1,
83   EXCH_PHASE_TEMP_TO_FROM= 2
84 };
85 
86 
87 typedef struct st_ddl_log_entry
88 {
89   const char *name;
90   const char *from_name;
91   const char *handler_name;
92   const char *tmp_name;
93   uint next_entry;
94   uint entry_pos;
95   enum ddl_log_entry_code entry_type;
96   enum ddl_log_action_code action_type;
97   /*
98     Most actions have only one phase. REPLACE does however have two
99     phases. The first phase removes the file with the new name if
100     there was one there before and the second phase renames the
101     old name to the new name.
102   */
103   char phase;
104 } DDL_LOG_ENTRY;
105 
106 typedef struct st_ddl_log_memory_entry
107 {
108   uint entry_pos;
109   struct st_ddl_log_memory_entry *next_log_entry;
110   struct st_ddl_log_memory_entry *prev_log_entry;
111   struct st_ddl_log_memory_entry *next_active_log_entry;
112 } DDL_LOG_MEMORY_ENTRY;
113 
114 
115 enum enum_explain_filename_mode
116 {
117   EXPLAIN_ALL_VERBOSE= 0,
118   EXPLAIN_PARTITIONS_VERBOSE,
119   EXPLAIN_PARTITIONS_AS_COMMENT
120 };
121 
122 
123 /* depends on errmsg.txt Database `db`, Table `t` ... */
124 #define EXPLAIN_FILENAME_MAX_EXTRA_LENGTH 63
125 
126 #define WFRM_WRITE_SHADOW 1
127 #define WFRM_INSTALL_SHADOW 2
128 #define WFRM_KEEP_SHARE 4
129 
130 /* Flags for conversion functions. */
131 static const uint FN_FROM_IS_TMP=  1 << 0;
132 static const uint FN_TO_IS_TMP=    1 << 1;
133 static const uint FN_IS_TMP=       FN_FROM_IS_TMP | FN_TO_IS_TMP;
134 static const uint NO_FRM_RENAME=   1 << 2;
135 static const uint FRM_ONLY=        1 << 3;
136 /** Don't remove table in engine. Remove only .FRM and maybe .PAR files. */
137 static const uint NO_HA_TABLE=     1 << 4;
138 /** Don't resolve MySQL's fake "foo.sym" symbolic directory names. */
139 static const uint SKIP_SYMDIR_ACCESS= 1 << 5;
140 /** Don't check foreign key constraints while renaming table */
141 static const uint NO_FK_CHECKS=    1 << 6;
142 /* Don't delete .par table in quick_rm_table() */
143 static const uint NO_PAR_TABLE=   1 << 7;
144 
145 uint filename_to_tablename(const char *from, char *to, size_t to_length,
146                            bool stay_quiet = false);
147 uint tablename_to_filename(const char *from, char *to, size_t to_length);
148 uint check_n_cut_mysql50_prefix(const char *from, char *to, size_t to_length);
149 bool check_mysql50_prefix(const char *name);
150 uint build_table_filename(char *buff, size_t bufflen, const char *db,
151                           const char *table, const char *ext, uint flags);
152 uint build_table_shadow_filename(char *buff, size_t bufflen,
153                                  ALTER_PARTITION_PARAM_TYPE *lpt);
154 uint build_tmptable_filename(THD* thd, char *buff, size_t bufflen);
155 bool mysql_create_table(THD *thd, TABLE_LIST *create_table,
156                         Table_specification_st *create_info,
157                         Alter_info *alter_info);
158 bool add_keyword_to_query(THD *thd, String *result, const LEX_CSTRING *keyword,
159                           const LEX_CSTRING *add);
160 
161 /*
162   mysql_create_table_no_lock can be called in one of the following
163   mutually exclusive situations:
164 
165   - Just a normal ordinary CREATE TABLE statement that explicitly
166     defines the table structure.
167 
168   - CREATE TABLE ... SELECT. It is special, because only in this case,
169     the list of fields is allowed to have duplicates, as long as one of the
170     duplicates comes from the select list, and the other doesn't. For
171     example in
172 
173        CREATE TABLE t1 (a int(5) NOT NUL) SELECT b+10 as a FROM t2;
174 
175     the list in alter_info->create_list will have two fields `a`.
176 
177   - ALTER TABLE, that creates a temporary table #sql-xxx, which will be later
178     renamed to replace the original table.
179 
180   - ALTER TABLE as above, but which only modifies the frm file, it only
181     creates an frm file for the #sql-xxx, the table in the engine is not
182     created.
183 
184   - Assisted discovery, CREATE TABLE statement without the table structure.
185 
186   These situations are distinguished by the following "create table mode"
187   values, where a CREATE ... SELECT is denoted by any non-negative number
188   (which should be the number of fields in the SELECT ... part), and other
189   cases use constants as defined below.
190 */
191 #define C_CREATE_SELECT(X)        ((X) > 0 ? (X) : 0)
192 #define C_ORDINARY_CREATE         0
193 #define C_ALTER_TABLE            -1
194 #define C_ALTER_TABLE_FRM_ONLY   -2
195 #define C_ASSISTED_DISCOVERY     -3
196 
197 int mysql_create_table_no_lock(THD *thd, const LEX_CSTRING *db,
198                                const LEX_CSTRING *table_name,
199                                Table_specification_st *create_info,
200                                Alter_info *alter_info, bool *is_trans,
201                                int create_table_mode, TABLE_LIST *table);
202 
203 handler *mysql_create_frm_image(THD *thd,
204                                 const LEX_CSTRING &db,
205                                 const LEX_CSTRING &table_name,
206                                 HA_CREATE_INFO *create_info,
207                                 Alter_info *alter_info,
208                                 int create_table_mode,
209                                 KEY **key_info,
210                                 uint *key_count,
211                                 LEX_CUSTRING *frm);
212 
213 int mysql_discard_or_import_tablespace(THD *thd,
214                                        TABLE_LIST *table_list,
215                                        bool discard);
216 
217 bool mysql_prepare_alter_table(THD *thd, TABLE *table,
218                                HA_CREATE_INFO *create_info,
219                                Alter_info *alter_info,
220                                Alter_table_ctx *alter_ctx);
221 bool mysql_trans_prepare_alter_copy_data(THD *thd);
222 bool mysql_trans_commit_alter_copy_data(THD *thd);
223 bool mysql_alter_table(THD *thd, const LEX_CSTRING *new_db,
224                        const LEX_CSTRING *new_name,
225                        HA_CREATE_INFO *create_info,
226                        TABLE_LIST *table_list,
227                        Alter_info *alter_info,
228                        uint order_num, ORDER *order, bool ignore,
229                        bool if_exists);
230 bool mysql_compare_tables(TABLE *table,
231                           Alter_info *alter_info,
232                           HA_CREATE_INFO *create_info,
233                           bool *metadata_equal);
234 bool mysql_recreate_table(THD *thd, TABLE_LIST *table_list, bool table_copy);
235 bool mysql_create_like_table(THD *thd, TABLE_LIST *table,
236                              TABLE_LIST *src_table,
237                              Table_specification_st *create_info);
238 bool mysql_rename_table(handlerton *base, const LEX_CSTRING *old_db,
239                         const LEX_CSTRING *old_name, const LEX_CSTRING *new_db,
240                         const LEX_CSTRING *new_name, uint flags);
241 
242 bool mysql_backup_table(THD* thd, TABLE_LIST* table_list);
243 bool mysql_restore_table(THD* thd, TABLE_LIST* table_list);
244 
245 bool mysql_checksum_table(THD* thd, TABLE_LIST* table_list,
246                           HA_CHECK_OPT* check_opt);
247 bool mysql_rm_table(THD *thd,TABLE_LIST *tables, bool if_exists,
248                     bool drop_temporary, bool drop_sequence,
249                     bool dont_log_query);
250 int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists,
251                             bool drop_temporary, bool drop_view,
252                             bool drop_sequence,
253                             bool dont_log_query, bool dont_free_locks);
254 bool log_drop_table(THD *thd, const LEX_CSTRING *db_name,
255                     const LEX_CSTRING *table_name, bool temporary_table);
256 bool quick_rm_table(THD *thd, handlerton *base, const LEX_CSTRING *db,
257                     const LEX_CSTRING *table_name, uint flags,
258                     const char *table_path=0);
259 void close_cached_table(THD *thd, TABLE *table);
260 void sp_prepare_create_field(THD *thd, Column_definition *sql_field);
261 bool mysql_write_frm(ALTER_PARTITION_PARAM_TYPE *lpt, uint flags);
262 int write_bin_log(THD *thd, bool clear_error,
263                   char const *query, ulong query_length,
264                   bool is_trans= FALSE);
265 int write_bin_log_with_if_exists(THD *thd, bool clear_error,
266                                  bool is_trans, bool add_if_exists);
267 bool write_ddl_log_entry(DDL_LOG_ENTRY *ddl_log_entry,
268                            DDL_LOG_MEMORY_ENTRY **active_entry);
269 bool write_execute_ddl_log_entry(uint first_entry,
270                                    bool complete,
271                                    DDL_LOG_MEMORY_ENTRY **active_entry);
272 bool deactivate_ddl_log_entry(uint entry_no);
273 void release_ddl_log_memory_entry(DDL_LOG_MEMORY_ENTRY *log_entry);
274 bool sync_ddl_log();
275 void release_ddl_log();
276 void execute_ddl_log_recovery();
277 bool execute_ddl_log_entry(THD *thd, uint first_entry);
278 
279 template<typename T> class List;
280 void promote_first_timestamp_column(List<Create_field> *column_definitions);
281 
282 /*
283   These prototypes where under INNODB_COMPATIBILITY_HOOKS.
284 */
285 uint explain_filename(THD* thd, const char *from, char *to, uint to_length,
286                       enum_explain_filename_mode explain_mode);
287 
288 
289 extern MYSQL_PLUGIN_IMPORT const char *primary_key_name;
290 extern mysql_mutex_t LOCK_gdl;
291 
292 bool check_engine(THD *, const char *, const char *, HA_CREATE_INFO *);
293 
294 #endif /* SQL_TABLE_INCLUDED */
295