1 /* Copyright (c) 2010, 2020, Oracle and/or its affiliates. All rights reserved.
2 
3    This program is free software; you can redistribute it and/or modify
4    it under the terms of the GNU General Public License, version 2.0,
5    as published by the Free Software Foundation.
6 
7    This program is also distributed with certain software (including
8    but not limited to OpenSSL) that is licensed under separate terms,
9    as designated in a particular file or component or in included license
10    documentation.  The authors of MySQL hereby grant you an additional
11    permission to link the program and your derivative works with the
12    separately licensed software that they have included with MySQL.
13 
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License, version 2.0, for more details.
18 
19    You should have received a copy of the GNU General Public License
20    along with this program; if not, write to the Free Software
21    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA */
22 
23 #ifndef SQL_TABLE_MAINTENANCE_H
24 #define SQL_TABLE_MAINTENANCE_H
25 
26 #include <stddef.h>
27 #include <set>
28 
29 #include "lex_string.h"
30 #include "my_dbug.h"
31 #include "my_sqlcommand.h"
32 #include "sql/histograms/histogram.h"
33 #include "sql/mem_root_allocator.h"
34 #include "sql/sql_cmd.h"            // Sql_cmd
35 #include "sql/sql_cmd_ddl_table.h"  // Sql_cmd_ddl_table
36 #include "sql/sql_plugin_ref.h"
37 
38 class Clone_handler;
39 class String;
40 class THD;
41 
42 struct TABLE_LIST;
43 template <class T>
44 class List;
45 
46 struct KEY_CACHE;
47 struct LEX_USER;
48 
49 struct Column_name_comparator {
50   bool operator()(const String *lhs, const String *rhs) const;
51 };
52 
53 /* Must be able to hold ALTER TABLE t PARTITION BY ... KEY ALGORITHM = 1 ... */
54 #define SQL_ADMIN_MSG_TEXT_SIZE 128 * 1024
55 
56 /**
57   Sql_cmd_analyze_table represents the ANALYZE TABLE statement.
58 
59   Also this class is a base class for Sql_cmd_alter_table_analyze_partition
60   which represents the ALTER TABLE ... ANALYZE PARTITION statement.
61 */
62 class Sql_cmd_analyze_table : public Sql_cmd_ddl_table {
63  public:
64   /**
65     Specifies which (if any) of the commands UPDATE HISTOGRAM or DROP HISTOGRAM
66     that is specified after ANALYZE TABLE tbl.
67   */
68   enum class Histogram_command {
69     NONE,              ///< Neither UPDATE or DROP histogram is specified
70     UPDATE_HISTOGRAM,  ///< UPDATE HISTOGRAM ... is specified after ANALYZE
71                        ///< TABLE
72     DROP_HISTOGRAM     ///< DROP HISTOGRAM ... is specified after ANALYZE TABLE
73   };
74 
75   /**
76     Constructor, used to represent a ANALYZE TABLE statement.
77   */
78   Sql_cmd_analyze_table(THD *thd, Alter_info *alter_info,
79                         Histogram_command histogram_command,
80                         int histogram_buckets);
81 
82   bool execute(THD *thd) override;
83 
sql_command_code()84   enum_sql_command sql_command_code() const override { return SQLCOM_ANALYZE; }
85 
86   /**
87     Set which fields to (try and) create/update or delete histogram statistics
88     for.
89   */
90   bool set_histogram_fields(List<String> *fields);
91 
92  private:
93   using columns_set =
94       std::set<String *, Column_name_comparator, Mem_root_allocator<String *>>;
95 
96   /// Which histogram command (if any) is specified
97   Histogram_command m_histogram_command = Histogram_command::NONE;
98 
99   /// The fields specified by the user in UPDATE/DROP HISTOGRAM
100   columns_set m_histogram_fields;
101 
102   /// The number of buckets specified by the user in UPDATE HISTOGRAM
103   int m_histogram_buckets;
104 
105   /// @return The histogram command specified, if any.
get_histogram_command()106   Histogram_command get_histogram_command() const {
107     return m_histogram_command;
108   }
109 
110   /// @return The number of buckets specified in UPDATE HISTOGRAM.
get_histogram_buckets()111   int get_histogram_buckets() const { return m_histogram_buckets; }
112 
113   /// @return The fields specified in UPDATE/DROP HISTOGRAM
get_histogram_fields()114   const columns_set &get_histogram_fields() const { return m_histogram_fields; }
115 
116   /**
117     Send the result of histogram operations back to the client as a result set.
118 
119     @param thd      Thread handle.
120     @param results  The messages to send back to the client.
121     @param table    The table the operations was performed on.
122 
123     @return false on success, true otherwise.
124   */
125   bool send_histogram_results(THD *thd, const histograms::results_map &results,
126                               const TABLE_LIST *table);
127 
128   /**
129     Update one or more histograms
130 
131     This is invoked by running the command "ANALYZE TABLE tbl UPDATE HISTOGRAM
132     ON col1, col2 WITH n BUCKETS". Note that the function expects exactly one
133     table to be specified, but multiple columns can be specified.
134 
135     @param thd Thread handler.
136     @param table The table specified in ANALYZE TABLE
137     @param results A map where the results of the operations will be stored.
138 
139     @return false on success, true on error.
140   */
141   bool update_histogram(THD *thd, TABLE_LIST *table,
142                         histograms::results_map &results);
143 
144   /**
145     Drops one or more histograms
146 
147     This is invoked by running the command "ANALYZE TABLE tbl DROP HISTOGRAM ON
148     col1, col2;". Note that the function expects exactly one table to be
149     specified, but multiple columns can be specified.
150 
151     @param thd Thread handler.
152     @param table The table specified in ANALYZE TABLE
153     @param results A map where the results of the operations will be stored.
154 
155     @return false on success, true on error.
156   */
157   bool drop_histogram(THD *thd, TABLE_LIST *table,
158                       histograms::results_map &results);
159 
160   bool handle_histogram_command(THD *thd, TABLE_LIST *table);
161 };
162 
163 /**
164   Sql_cmd_check_table represents the CHECK TABLE statement.
165 
166   Also this is a base class of Sql_cmd_alter_table_check_partition which
167   represents the ALTER TABLE ... CHECK PARTITION statement.
168 */
169 class Sql_cmd_check_table : public Sql_cmd_ddl_table {
170  public:
171   using Sql_cmd_ddl_table::Sql_cmd_ddl_table;
172 
173   bool execute(THD *thd);
174 
sql_command_code()175   virtual enum_sql_command sql_command_code() const { return SQLCOM_CHECK; }
176 };
177 
178 /**
179   Sql_cmd_optimize_table represents the OPTIMIZE TABLE statement.
180 
181   Also this is a base class of Sql_cmd_alter_table_optimize_partition.
182   represents the ALTER TABLE ... CHECK PARTITION statement.
183 */
184 class Sql_cmd_optimize_table : public Sql_cmd_ddl_table {
185  public:
186   using Sql_cmd_ddl_table::Sql_cmd_ddl_table;
187 
188   bool execute(THD *thd);
189 
sql_command_code()190   virtual enum_sql_command sql_command_code() const { return SQLCOM_OPTIMIZE; }
191 };
192 
193 /**
194   Sql_cmd_repair_table represents the REPAIR TABLE statement.
195 
196   Also this is a base class of Sql_cmd_alter_table_repair_partition which
197   represents the ALTER TABLE ... REPAIR PARTITION statement.
198 */
199 class Sql_cmd_repair_table : public Sql_cmd_ddl_table {
200  public:
201   using Sql_cmd_ddl_table::Sql_cmd_ddl_table;
202 
203   bool execute(THD *thd);
204 
sql_command_code()205   virtual enum_sql_command sql_command_code() const { return SQLCOM_REPAIR; }
206 };
207 
208 /**
209   Sql_cmd_shutdown represents the SHUTDOWN statement.
210 */
211 class Sql_cmd_shutdown : public Sql_cmd {
212  public:
213   virtual bool execute(THD *thd);
sql_command_code()214   virtual enum_sql_command sql_command_code() const { return SQLCOM_SHUTDOWN; }
215 };
216 
217 enum class role_enum { ROLE_NONE, ROLE_DEFAULT, ROLE_ALL, ROLE_NAME };
218 
219 /**
220   Sql_cmd_set_role represetns the SET ROLE ... statement.
221 */
222 class Sql_cmd_set_role : public Sql_cmd {
223   friend class PT_set_role;
224 
225   const role_enum role_type;
226   const List<LEX_USER> *role_list;
227   const List<LEX_USER> *except_roles;
228 
229  public:
Sql_cmd_set_role(role_enum role_type_arg,const List<LEX_USER> * except_roles_arg)230   Sql_cmd_set_role(role_enum role_type_arg,
231                    const List<LEX_USER> *except_roles_arg)
232       : role_type(role_type_arg),
233         role_list(nullptr),
234         except_roles(except_roles_arg) {
235     DBUG_ASSERT(role_type == role_enum::ROLE_NONE ||
236                 role_type == role_enum::ROLE_DEFAULT ||
237                 role_type == role_enum::ROLE_ALL);
238     DBUG_ASSERT(role_type == role_enum::ROLE_ALL || except_roles == nullptr);
239   }
Sql_cmd_set_role(const List<LEX_USER> * role_arg)240   explicit Sql_cmd_set_role(const List<LEX_USER> *role_arg)
241       : role_type(role_enum::ROLE_NAME), role_list(role_arg) {}
242 
243   virtual bool execute(THD *thd);
sql_command_code()244   virtual enum_sql_command sql_command_code() const { return SQLCOM_SET_ROLE; }
245 };
246 
247 /**
248   Sql_cmd_create_role represetns the CREATE ROLE ... statement.
249 */
250 class Sql_cmd_create_role : public Sql_cmd {
251   friend class PT_create_role;
252 
253   const bool if_not_exists;
254   const List<LEX_USER> *roles;
255 
256  public:
Sql_cmd_create_role(bool if_not_exists_arg,const List<LEX_USER> * roles_arg)257   explicit Sql_cmd_create_role(bool if_not_exists_arg,
258                                const List<LEX_USER> *roles_arg)
259       : if_not_exists(if_not_exists_arg), roles(roles_arg) {}
260 
261   virtual bool execute(THD *thd);
sql_command_code()262   virtual enum_sql_command sql_command_code() const {
263     return SQLCOM_CREATE_ROLE;
264   }
265 };
266 
267 /**
268   Sql_cmd_drop_role represetns the DROP ROLE ... statement.
269 */
270 class Sql_cmd_drop_role : public Sql_cmd {
271   friend class PT_drop_role;
272 
273   bool ignore_errors;
274   const List<LEX_USER> *roles;
275 
276  public:
Sql_cmd_drop_role(bool ignore_errors_arg,const List<LEX_USER> * roles_arg)277   explicit Sql_cmd_drop_role(bool ignore_errors_arg,
278                              const List<LEX_USER> *roles_arg)
279       : ignore_errors(ignore_errors_arg), roles(roles_arg) {}
280 
281   virtual bool execute(THD *thd);
sql_command_code()282   virtual enum_sql_command sql_command_code() const { return SQLCOM_DROP_ROLE; }
283 };
284 
285 /**
286   Sql_cmd_grant_roles represents the GRANT role-list TO ... statement.
287 */
288 class Sql_cmd_grant_roles : public Sql_cmd {
289   const List<LEX_USER> *roles;
290   const List<LEX_USER> *users;
291   const bool with_admin_option;
292 
293  public:
Sql_cmd_grant_roles(const List<LEX_USER> * roles_arg,const List<LEX_USER> * users_arg,bool with_admin_option_arg)294   explicit Sql_cmd_grant_roles(const List<LEX_USER> *roles_arg,
295                                const List<LEX_USER> *users_arg,
296                                bool with_admin_option_arg)
297       : roles(roles_arg),
298         users(users_arg),
299         with_admin_option(with_admin_option_arg) {}
300 
301   virtual bool execute(THD *thd);
sql_command_code()302   virtual enum_sql_command sql_command_code() const {
303     return SQLCOM_GRANT_ROLE;
304   }
305 };
306 
307 /**
308   Sql_cmd_revoke_roles represents the REVOKE [role list] TO ... statement.
309 */
310 class Sql_cmd_revoke_roles : public Sql_cmd {
311   const List<LEX_USER> *roles;
312   const List<LEX_USER> *users;
313 
314  public:
Sql_cmd_revoke_roles(const List<LEX_USER> * roles_arg,const List<LEX_USER> * users_arg)315   explicit Sql_cmd_revoke_roles(const List<LEX_USER> *roles_arg,
316                                 const List<LEX_USER> *users_arg)
317       : roles(roles_arg), users(users_arg) {}
318 
319   virtual bool execute(THD *thd);
sql_command_code()320   virtual enum_sql_command sql_command_code() const {
321     return SQLCOM_REVOKE_ROLE;
322   }
323 };
324 
325 /**
326   Sql_cmd_alter_user_default_role ALTER USER ... DEFAULT ROLE ... statement.
327 */
328 class Sql_cmd_alter_user_default_role : public Sql_cmd {
329   friend class PT_alter_user_default_role;
330 
331   const bool if_exists;
332   const List<LEX_USER> *users;
333   const List<LEX_USER> *roles;
334   const role_enum role_type;
335 
336  public:
Sql_cmd_alter_user_default_role(bool if_exists_arg,const List<LEX_USER> * users_arg,const List<LEX_USER> * roles_arg,const role_enum role_type_arg)337   explicit Sql_cmd_alter_user_default_role(bool if_exists_arg,
338                                            const List<LEX_USER> *users_arg,
339                                            const List<LEX_USER> *roles_arg,
340                                            const role_enum role_type_arg)
341       : if_exists(if_exists_arg),
342         users(users_arg),
343         roles(roles_arg),
344         role_type(role_type_arg) {}
345 
346   virtual bool execute(THD *thd);
sql_command_code()347   virtual enum_sql_command sql_command_code() const {
348     return SQLCOM_ALTER_USER_DEFAULT_ROLE;
349   }
350 };
351 
352 /**
353   Sql_cmd_show_grants SHOW GRANTS ... statement.
354 */
355 class Sql_cmd_show_grants : public Sql_cmd {
356   friend class PT_show_grants;
357 
358   const LEX_USER *for_user;
359   const List<LEX_USER> *using_users;
360 
361  public:
Sql_cmd_show_grants(const LEX_USER * for_user_arg,const List<LEX_USER> * using_users_arg)362   Sql_cmd_show_grants(const LEX_USER *for_user_arg,
363                       const List<LEX_USER> *using_users_arg)
364       : for_user(for_user_arg), using_users(using_users_arg) {}
365 
366   virtual bool execute(THD *thd);
sql_command_code()367   virtual enum_sql_command sql_command_code() const {
368     return SQLCOM_SHOW_GRANTS;
369   }
370 };
371 
372 enum alter_instance_action_enum {
373   ROTATE_INNODB_MASTER_KEY,
374   ALTER_INSTANCE_RELOAD_TLS,
375   ALTER_INSTANCE_RELOAD_TLS_ROLLBACK_ON_ERROR,
376   ROTATE_BINLOG_MASTER_KEY,
377   LAST_MASTER_KEY, /* Add new master key type before this */
378   ALTER_INSTANCE_ENABLE_INNODB_REDO,
379   ALTER_INSTANCE_DISABLE_INNODB_REDO
380 };
381 
382 /**
383   Sql_cmd_alter_instance represents the ROTATE alter_instance_action MASTER KEY
384   statement.
385 */
386 class Alter_instance;
387 
388 class Sql_cmd_alter_instance : public Sql_cmd {
389   friend class PT_alter_instance;
390   const enum alter_instance_action_enum alter_instance_action;
391   LEX_CSTRING channel_name_;
392   Alter_instance *alter_instance;
393 
394  public:
Sql_cmd_alter_instance(enum alter_instance_action_enum alter_instance_action_arg,const LEX_CSTRING & channel_name)395   explicit Sql_cmd_alter_instance(
396       enum alter_instance_action_enum alter_instance_action_arg,
397       const LEX_CSTRING &channel_name)
398       : alter_instance_action(alter_instance_action_arg),
399         channel_name_(channel_name),
400         alter_instance(nullptr) {}
401 
402   virtual bool execute(THD *thd);
sql_command_code()403   virtual enum_sql_command sql_command_code() const {
404     return SQLCOM_ALTER_INSTANCE;
405   }
406 };
407 
408 /**
409   Sql_cmd_clone implements CLONE ... statement.
410 */
411 
412 class Sql_cmd_clone : public Sql_cmd {
413  public:
414   /** Construct clone command for clone server */
Sql_cmd_clone()415   explicit Sql_cmd_clone()
416       : m_host(),
417         m_port(),
418         m_user(),
419         m_passwd(),
420         m_data_dir(),
421         m_clone(),
422         m_is_local(false) {}
423 
424   /** Construct clone command for clone client
425   @param[in]  user_info user, password and remote host information
426   @param[in]  port port for remote server
427   @param[in]  data_dir data directory to clone */
428   explicit Sql_cmd_clone(LEX_USER *user_info, ulong port, LEX_CSTRING data_dir);
429 
430   /** Construct clone command for local clone
431   @param[in]  data_dir data directory to clone */
Sql_cmd_clone(LEX_CSTRING data_dir)432   explicit Sql_cmd_clone(LEX_CSTRING data_dir)
433       : m_host(),
434         m_port(),
435         m_user(),
436         m_passwd(),
437         m_data_dir(data_dir),
438         m_clone(),
439         m_is_local(true) {}
440 
sql_command_code()441   virtual enum_sql_command sql_command_code() const { return SQLCOM_CLONE; }
442 
443   virtual bool execute(THD *thd);
444 
445   /** Execute clone server.
446   @param[in] thd server session
447   @return true, if error */
448   bool execute_server(THD *thd);
449 
450   /** Load clone plugin for clone server.
451   @param[in] thd server session
452   @return true, if error */
453   bool load(THD *thd);
454 
455   /** Re-write clone statement to hide password.
456   @param[in,out] thd server session
457   @param[in,out] rlb the buffer to return the rewritten query in. empty if none.
458   @return true iff query is re-written */
459   bool rewrite(THD *thd, String &rlb);
460 
461   /** @return true, if it is local clone command */
is_local()462   bool is_local() const { return (m_is_local); }
463 
464  private:
465   /** Remote server IP */
466   LEX_CSTRING m_host;
467 
468   /** Remote server port */
469   const ulong m_port;
470 
471   /** User name for remote connection */
472   LEX_CSTRING m_user;
473 
474   /** Password for remote connection */
475   LEX_CSTRING m_passwd;
476 
477   /** Data directory for cloned data */
478   LEX_CSTRING m_data_dir;
479 
480   /** Clone handle in server */
481   Clone_handler *m_clone;
482 
483   /** Loaded clone plugin reference */
484   plugin_ref m_plugin;
485 
486   /** If it is local clone operation */
487   bool m_is_local;
488 };
489 
490 /**
491   Sql_cmd_show represents the SHOW COLUMNS/SHOW INDEX statements.
492 */
493 class Sql_cmd_show : public Sql_cmd {
494  public:
Sql_cmd_show(enum_sql_command sql_command)495   Sql_cmd_show(enum_sql_command sql_command) : m_sql_command(sql_command) {}
496   virtual bool execute(THD *thd);
sql_command_code()497   virtual enum_sql_command sql_command_code() const { return m_sql_command; }
498   virtual bool prepare(THD *thd);
499 
500  private:
501   enum_sql_command m_sql_command;
502 };
503 
504 #endif
505