1 /* Copyright (c) 2014, 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 DD__TABLE_INCLUDED
24 #define DD__TABLE_INCLUDED
25 
26 #include "lex_string.h"     // LEX_CSTRING
27 #include "mysql_version.h"  // MYSQL_VERSION_ID
28 
29 #include "sql/dd/sdi_fwd.h"               // Sdi_wcontext
30 #include "sql/dd/types/abstract_table.h"  // dd::Abstract_table
31 #include "sql/dd/types/foreign_key.h"     // IWYU pragma: keep
32 #include "sql/dd/types/index.h"           // IWYU pragma: keep
33 #include "sql/dd/types/trigger.h"         // dd::Trigger::enum_*
34 
35 namespace dd {
36 
37 ///////////////////////////////////////////////////////////////////////////
38 
39 class Check_constraint;
40 class Partition;
41 class Table_impl;
42 class Trigger;
43 
44 ///////////////////////////////////////////////////////////////////////////
45 
46 class Table : virtual public Abstract_table {
47  public:
48   typedef Table_impl Impl;
49   typedef Collection<Index *> Index_collection;
50   typedef Collection<Foreign_key *> Foreign_key_collection;
51   typedef std::vector<Foreign_key_parent *> Foreign_key_parent_collection;
52   typedef Collection<Partition *> Partition_collection;
53   typedef Collection<Trigger *> Trigger_collection;
54   typedef Collection<Check_constraint *> Check_constraint_collection;
55 
56   /*
57     The type Partition_collection object 'own' the Partition* object. That
58     means that the object Partition* would be deleted when the
59     Partition_collection is deleted. However the Partition_leaf_vector type
60     does not 'own' the Partition* object and points to one of element
61     owned by Partition_collection. Deleting Partition_leaf_vector will not
62     delete the Partition* objects pointed by it.
63   */
64   typedef std::vector<Partition *> Partition_leaf_vector;
65 
66   // We need a set of functions to update a preallocated se private id key,
67   // which requires special handling for table objects.
update_aux_key(Aux_key * key)68   virtual bool update_aux_key(Aux_key *key) const {
69     return update_aux_key(key, engine(), se_private_id());
70   }
71 
72   static bool update_aux_key(Aux_key *key, const String_type &engine,
73                              Object_id se_private_id);
74 
75  public:
~Table()76   virtual ~Table() {}
77 
78  public:
79   enum enum_row_format {
80     RF_FIXED = 1,
81     RF_DYNAMIC,
82     RF_COMPRESSED,
83     RF_REDUNDANT,
84     RF_COMPACT,
85     RF_PAGED
86   };
87 
88   /* Keep in sync with subpartition type for forward compatibility.*/
89   enum enum_partition_type {
90     PT_NONE = 0,
91     PT_HASH,
92     PT_KEY_51,
93     PT_KEY_55,
94     PT_LINEAR_HASH,
95     PT_LINEAR_KEY_51,
96     PT_LINEAR_KEY_55,
97     PT_RANGE,
98     PT_LIST,
99     PT_RANGE_COLUMNS,
100     PT_LIST_COLUMNS,
101     PT_AUTO,
102     PT_AUTO_LINEAR,
103   };
104 
105   enum enum_subpartition_type {
106     ST_NONE = 0,
107     ST_HASH,
108     ST_KEY_51,
109     ST_KEY_55,
110     ST_LINEAR_HASH,
111     ST_LINEAR_KEY_51,
112     ST_LINEAR_KEY_55
113   };
114 
115   /* Also used for default subpartitioning. */
116   enum enum_default_partitioning { DP_NONE = 0, DP_NO, DP_YES, DP_NUMBER };
117 
118  public:
119   /////////////////////////////////////////////////////////////////////////
120   // is_temporary.
121   /////////////////////////////////////////////////////////////////////////
122 
123   virtual bool is_temporary() const = 0;
124   virtual void set_is_temporary(bool is_temporary) = 0;
125 
126   /////////////////////////////////////////////////////////////////////////
127   // collation.
128   /////////////////////////////////////////////////////////////////////////
129 
130   virtual Object_id collation_id() const = 0;
131   virtual void set_collation_id(Object_id collation_id) = 0;
132 
133   /////////////////////////////////////////////////////////////////////////
134   // tablespace.
135   /////////////////////////////////////////////////////////////////////////
136 
137   virtual Object_id tablespace_id() const = 0;
138   virtual void set_tablespace_id(Object_id tablespace_id) = 0;
139   virtual bool is_explicit_tablespace() const = 0;
140 
141   /////////////////////////////////////////////////////////////////////////
142   // engine.
143   /////////////////////////////////////////////////////////////////////////
144 
145   virtual const String_type &engine() const = 0;
146   virtual void set_engine(const String_type &engine) = 0;
147 
148   /////////////////////////////////////////////////////////////////////////
149   // row_format
150   /////////////////////////////////////////////////////////////////////////
151   virtual enum_row_format row_format() const = 0;
152   virtual void set_row_format(enum_row_format row_format) = 0;
153 
154   /////////////////////////////////////////////////////////////////////////
155   // comment
156   /////////////////////////////////////////////////////////////////////////
157 
158   virtual const String_type &comment() const = 0;
159   virtual void set_comment(const String_type &comment) = 0;
160 
161   /////////////////////////////////////////////////////////////////////////
162   // last_checked_for_upgrade_version_id api
163   /////////////////////////////////////////////////////////////////////////
164 
165   virtual uint last_checked_for_upgrade_version_id() const = 0;
166   virtual void mark_as_checked_for_upgrade() = 0;
167 
168   /////////////////////////////////////////////////////////////////////////
169   // se_private_data.
170   /////////////////////////////////////////////////////////////////////////
171 
172   virtual const Properties &se_private_data() const = 0;
173 
174   virtual Properties &se_private_data() = 0;
175   virtual bool set_se_private_data(const String_type &se_private_data_raw) = 0;
176   virtual bool set_se_private_data(const Properties &se_private_data) = 0;
177 
178   /////////////////////////////////////////////////////////////////////////
179   // se_private_id.
180   /////////////////////////////////////////////////////////////////////////
181 
182   virtual Object_id se_private_id() const = 0;
183   virtual void set_se_private_id(Object_id se_private_id) = 0;
184 
185   /////////////////////////////////////////////////////////////////////////
186   // SE-specific json attributes
187   /////////////////////////////////////////////////////////////////////////
188 
189   virtual LEX_CSTRING engine_attribute() const = 0;
190   virtual void set_engine_attribute(LEX_CSTRING attrs) = 0;
191 
192   virtual LEX_CSTRING secondary_engine_attribute() const = 0;
193   virtual void set_secondary_engine_attribute(LEX_CSTRING attrs) = 0;
194 
195   /////////////////////////////////////////////////////////////////////////
196   // Partition related.
197   /////////////////////////////////////////////////////////////////////////
198 
199   virtual enum_partition_type partition_type() const = 0;
200   virtual void set_partition_type(enum_partition_type partition_type) = 0;
201 
202   virtual enum_default_partitioning default_partitioning() const = 0;
203   virtual void set_default_partitioning(
204       enum_default_partitioning default_partitioning) = 0;
205 
206   virtual const String_type &partition_expression() const = 0;
207   virtual void set_partition_expression(
208       const String_type &partition_expression) = 0;
209 
210   virtual const String_type &partition_expression_utf8() const = 0;
211   virtual void set_partition_expression_utf8(
212       const String_type &partition_expression) = 0;
213 
214   virtual enum_subpartition_type subpartition_type() const = 0;
215   virtual void set_subpartition_type(
216       enum_subpartition_type subpartition_type) = 0;
217 
218   virtual enum_default_partitioning default_subpartitioning() const = 0;
219   virtual void set_default_subpartitioning(
220       enum_default_partitioning default_subpartitioning) = 0;
221 
222   virtual const String_type &subpartition_expression() const = 0;
223   virtual void set_subpartition_expression(
224       const String_type &subpartition_expression) = 0;
225 
226   virtual const String_type &subpartition_expression_utf8() const = 0;
227   virtual void set_subpartition_expression_utf8(
228       const String_type &subpartition_expression) = 0;
229 
230   /** Dummy method to be able to use Partition and Table interchangeably
231   in templates. */
table()232   const Table &table() const { return *this; }
table()233   Table &table() { return *this; }
234 
235   /////////////////////////////////////////////////////////////////////////
236   // Index collection.
237   /////////////////////////////////////////////////////////////////////////
238 
239   virtual Index *add_index() = 0;
240 
241   virtual Index *add_first_index() = 0;
242 
243   virtual const Index_collection &indexes() const = 0;
244 
245   virtual Index_collection *indexes() = 0;
246 
247   /////////////////////////////////////////////////////////////////////////
248   // Foreign key collection.
249   /////////////////////////////////////////////////////////////////////////
250 
251   virtual Foreign_key *add_foreign_key() = 0;
252 
253   virtual const Foreign_key_collection &foreign_keys() const = 0;
254 
255   virtual Foreign_key_collection *foreign_keys() = 0;
256 
257   /////////////////////////////////////////////////////////////////////////
258   // Foreign key parent collection.
259   /////////////////////////////////////////////////////////////////////////
260 
261   // The Foreign_key_parent_collection represents a list of tables that
262   // have a foreign key referencing this table. It is constructed when
263   // the dd::Table object is fetched from disk, and it can be reloaded
264   // from the DD tables on demand using 'reload_foreign_key_parents()'.
265 
266   virtual const Foreign_key_parent_collection &foreign_key_parents() const = 0;
267 
268   virtual bool reload_foreign_key_parents(THD *thd) = 0;
269 
270   /////////////////////////////////////////////////////////////////////////
271   // Partition collection.
272   /////////////////////////////////////////////////////////////////////////
273 
274   virtual Partition *add_partition() = 0;
275 
276   virtual const Partition_collection &partitions() const = 0;
277 
278   virtual Partition_collection *partitions() = 0;
279 
280   /*
281     This API to list only the leaf partition entries of a table. This depicts
282     the real physical partitions. In case of table with no sub-partitions,
283     this API returns list of all partitions. In case of table with
284     sub-partitions, the API lists only the sub-partition entries.
285 
286     @return Partition_leaf_vector  - List of pointers to dd::Partition objects.
287   */
288   virtual const Partition_leaf_vector &leaf_partitions() const = 0;
289 
290   virtual Partition_leaf_vector *leaf_partitions() = 0;
291 
292   /////////////////////////////////////////////////////////////////////////
293   // Trigger collection.
294   /////////////////////////////////////////////////////////////////////////
295 
296   /**
297     Check if table has any triggers.
298 
299     @return true  - if there are triggers on the table installed.
300     @return false - if not.
301   */
302 
303   virtual bool has_trigger() const = 0;
304 
305   /**
306     Get const reference to Trigger_collection.
307 
308     @return Trigger_collection& - Const reference to a collection of triggers.
309   */
310 
311   virtual const Trigger_collection &triggers() const = 0;
312 
313   /**
314     Get non-const pointer to Trigger_collection.
315 
316     @return Trigger_collection* - Pointer to collection of triggers.
317   */
318 
319   virtual Trigger_collection *triggers() = 0;
320 
321   /**
322     Copy all the triggers from another dd::Table object.
323 
324     @param tab_obj Pointer to Table from which the triggers are copied.
325   */
326 
327   virtual void copy_triggers(const Table *tab_obj) = 0;
328 
329   /**
330     Add new trigger to the table.
331 
332     @param at      - Action timing of the trigger to be added.
333     @param et      - Event type of the trigger to be added.
334 
335     @return Trigger* - Pointer to new Trigger that is added to table.
336   */
337 
338   virtual Trigger *add_trigger(Trigger::enum_action_timing at,
339                                Trigger::enum_event_type et) = 0;
340 
341   /**
342     Get dd::Trigger object for the given trigger name.
343 
344     @return Trigger* - Pointer to Trigger.
345   */
346 
347   virtual const Trigger *get_trigger(const char *name) const = 0;
348 
349   /**
350     Add new trigger just after the trigger specified in argument.
351 
352     @param trigger - dd::Trigger object after which the new
353                      trigger should be created.
354     @param at      - Action timing of the trigger to be added.
355     @param et      - Event type of the trigger to be added.
356 
357     @return Trigger* - Pointer to newly created dd::Trigger object.
358   */
359 
360   virtual Trigger *add_trigger_following(const Trigger *trigger,
361                                          Trigger::enum_action_timing at,
362                                          Trigger::enum_event_type et) = 0;
363 
364   /**
365     Add new trigger just before the trigger specified in argument.
366 
367     @param trigger - dd::Trigger object before which the new
368                      trigger should be created.
369     @param at      - Action timing of the trigger to be added.
370     @param et      - Event type of the trigger to be added.
371 
372     @return Trigger* - Pointer to newly created dd::Trigger object.
373   */
374 
375   virtual Trigger *add_trigger_preceding(const Trigger *trigger,
376                                          Trigger::enum_action_timing at,
377                                          Trigger::enum_event_type et) = 0;
378 
379   /**
380     Drop the given trigger object.
381 
382     The method returns void, as we just remove the trigger from
383     dd::Collection (dd::Table_impl::m_triggers) in memory. The
384     trigger will be removed from mysql.triggers DD table when the
385     dd::Table object is stored/updated.
386 
387     @param trigger - dd::Trigger object to be dropped.
388   */
389 
390   virtual void drop_trigger(const Trigger *trigger) = 0;
391 
392   /**
393     Drop all the trigger on this dd::Table object.
394 
395     The method returns void, as we just remove the trigger from
396     dd::Collection (dd::Table_impl::m_triggers) in memory. The
397     trigger will be removed from mysql.triggers DD table when the
398     dd::Table object is stored/updated.
399   */
400 
401   virtual void drop_all_triggers() = 0;
402 
403   /////////////////////////////////////////////////////////////////////////
404   // Check constraint collection.
405   /////////////////////////////////////////////////////////////////////////
406 
407   virtual Check_constraint *add_check_constraint() = 0;
408 
409   virtual const Check_constraint_collection &check_constraints() const = 0;
410 
411   virtual Check_constraint_collection *check_constraints() = 0;
412 
413  public:
414   /**
415     Allocate a new object graph and invoke the copy contructor for
416     each object.
417 
418     @return pointer to dynamically allocated copy
419   */
420   virtual Table *clone() const = 0;
421 
422   /**
423     Converts *this into json.
424 
425     Converts all member variables that are to be included in the sdi
426     into json by transforming them appropriately and passing them to
427     the rapidjson writer provided.
428 
429     @param wctx opaque context for data needed by serialization
430     @param w rapidjson writer which will perform conversion to json
431 
432   */
433 
434   virtual void serialize(Sdi_wcontext *wctx, Sdi_writer *w) const = 0;
435 
436   /**
437     Re-establishes the state of *this by reading sdi information from
438     the rapidjson DOM subobject provided.
439 
440     Cross-references encountered within this object are tracked in
441     sdictx, so that they can be updated when the entire object graph
442     has been established.
443 
444     @param rctx stores book-keeping information for the
445     deserialization process
446     @param val subobject of rapidjson DOM containing json
447     representation of this object
448   */
449 
450   virtual bool deserialize(Sdi_rcontext *rctx, const RJ_Value &val) = 0;
451 };
452 
453 ///////////////////////////////////////////////////////////////////////////
454 
is_checked_for_upgrade(const Table & t)455 inline bool is_checked_for_upgrade(const Table &t) {
456   return t.last_checked_for_upgrade_version_id() == MYSQL_VERSION_ID;
457 }
458 }  // namespace dd
459 
460 #endif  // DD__TABLE_INCLUDED
461