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_IMPL_INCLUDED
24 #define DD__TABLE_IMPL_INCLUDED
25 
26 #include <sys/types.h>
27 #include <memory>
28 #include <new>
29 #include <string>
30 
31 #include "my_inttypes.h"
32 #include "mysql_version.h"  // MYSQL_VERSION_ID
33 #include "sql/dd/impl/properties_impl.h"
34 #include "sql/dd/impl/raw/raw_record.h"
35 #include "sql/dd/impl/types/abstract_table_impl.h"  // dd::Abstract_table_impl
36 #include "sql/dd/impl/types/entity_object_impl.h"
37 #include "sql/dd/impl/types/weak_object_impl.h"
38 #include "sql/dd/object_id.h"
39 #include "sql/dd/sdi_fwd.h"
40 #include "sql/dd/string_type.h"
41 #include "sql/dd/types/abstract_table.h"
42 #include "sql/dd/types/check_constraint.h"  // dd::Check_constraint
43 #include "sql/dd/types/foreign_key.h"       // dd::Foreign_key
44 #include "sql/dd/types/index.h"             // dd::Index
45 #include "sql/dd/types/partition.h"         // dd::Partition
46 #include "sql/dd/types/table.h"             // dd:Table
47 #include "sql/dd/types/trigger.h"           // dd::Trigger
48 #include "sql/strfunc.h"
49 
50 namespace dd {
51 
52 ///////////////////////////////////////////////////////////////////////////
53 
54 class Column;
55 class Foreign_key;
56 class Index;
57 class Object_table;
58 class Open_dictionary_tables_ctx;
59 class Partition;
60 class Properties;
61 class Sdi_rcontext;
62 class Sdi_wcontext;
63 class Trigger_impl;
64 class Weak_object;
65 class Object_table;
66 
67 class Table_impl : public Abstract_table_impl, virtual public Table {
68  public:
69   Table_impl();
70 
71   virtual ~Table_impl();
72 
73  public:
74   /////////////////////////////////////////////////////////////////////////
75   // enum_table_type.
76   /////////////////////////////////////////////////////////////////////////
77 
type()78   virtual enum_table_type type() const { return enum_table_type::BASE_TABLE; }
79 
80  public:
81   static void register_tables(Open_dictionary_tables_ctx *otx);
82 
83   virtual bool validate() const;
84 
85   virtual bool restore_children(Open_dictionary_tables_ctx *otx);
86 
87   virtual bool store_children(Open_dictionary_tables_ctx *otx);
88 
89   virtual bool drop_children(Open_dictionary_tables_ctx *otx) const;
90 
91   virtual bool restore_attributes(const Raw_record &r);
92 
93   virtual bool store_attributes(Raw_record *r);
94 
95   void serialize(Sdi_wcontext *wctx, Sdi_writer *w) const;
96 
97   bool deserialize(Sdi_rcontext *rctx, const RJ_Value &val);
98 
99   virtual void debug_print(String_type &outb) const;
100 
101  private:
102   /**
103     Store the trigger object in DD table.
104 
105     @param otx  current Open_dictionary_tables_ctx
106 
107     @returns
108      false on success.
109      true on failure.
110   */
111   bool store_triggers(Open_dictionary_tables_ctx *otx);
112 
113  public:
114   /////////////////////////////////////////////////////////////////////////
115   // is_temporary.
116   /////////////////////////////////////////////////////////////////////////
117 
is_temporary()118   virtual bool is_temporary() const { return m_is_temporary; }
set_is_temporary(bool is_temporary)119   virtual void set_is_temporary(bool is_temporary) {
120     m_is_temporary = is_temporary;
121   }
122 
123   /////////////////////////////////////////////////////////////////////////
124   // collation.
125   /////////////////////////////////////////////////////////////////////////
126 
collation_id()127   virtual Object_id collation_id() const { return m_collation_id; }
128 
set_collation_id(Object_id collation_id)129   virtual void set_collation_id(Object_id collation_id) {
130     m_collation_id = collation_id;
131   }
132 
133   /////////////////////////////////////////////////////////////////////////
134   // tablespace.
135   /////////////////////////////////////////////////////////////////////////
136 
tablespace_id()137   virtual Object_id tablespace_id() const { return m_tablespace_id; }
138 
set_tablespace_id(Object_id tablespace_id)139   virtual void set_tablespace_id(Object_id tablespace_id) {
140     m_tablespace_id = tablespace_id;
141   }
142 
is_explicit_tablespace()143   virtual bool is_explicit_tablespace() const {
144     bool is_explicit = false;
145     if (options().exists("explicit_tablespace"))
146       options().get("explicit_tablespace", &is_explicit);
147     return is_explicit;
148   }
149 
150   /////////////////////////////////////////////////////////////////////////
151   // engine.
152   /////////////////////////////////////////////////////////////////////////
153 
engine()154   virtual const String_type &engine() const { return m_engine; }
155 
set_engine(const String_type & engine)156   virtual void set_engine(const String_type &engine) { m_engine = engine; }
157 
158   /////////////////////////////////////////////////////////////////////////
159   // row_format
160   /////////////////////////////////////////////////////////////////////////
161 
row_format()162   virtual enum_row_format row_format() const { return m_row_format; }
163 
set_row_format(enum_row_format row_format)164   virtual void set_row_format(enum_row_format row_format) {
165     m_row_format = row_format;
166   }
167 
168   /////////////////////////////////////////////////////////////////////////
169   // comment
170   /////////////////////////////////////////////////////////////////////////
171 
comment()172   virtual const String_type &comment() const { return m_comment; }
173 
set_comment(const String_type & comment)174   virtual void set_comment(const String_type &comment) { m_comment = comment; }
175 
176   /////////////////////////////////////////////////////////////////////////
177   // last_checked_for_upgrade_version_id
178   /////////////////////////////////////////////////////////////////////////
last_checked_for_upgrade_version_id()179   virtual uint last_checked_for_upgrade_version_id() const {
180     return m_last_checked_for_upgrade_version_id;
181   }
182 
mark_as_checked_for_upgrade()183   virtual void mark_as_checked_for_upgrade() {
184     m_last_checked_for_upgrade_version_id = MYSQL_VERSION_ID;
185   }
186 
187   /////////////////////////////////////////////////////////////////////////
188   // se_private_data.
189   /////////////////////////////////////////////////////////////////////////
190 
se_private_data()191   virtual const Properties &se_private_data() const {
192     return m_se_private_data;
193   }
194 
se_private_data()195   virtual Properties &se_private_data() { return m_se_private_data; }
196 
set_se_private_data(const String_type & se_private_data_raw)197   virtual bool set_se_private_data(const String_type &se_private_data_raw) {
198     return m_se_private_data.insert_values(se_private_data_raw);
199   }
200 
set_se_private_data(const Properties & se_private_data)201   virtual bool set_se_private_data(const Properties &se_private_data) {
202     return m_se_private_data.insert_values(se_private_data);
203   }
204 
205   /////////////////////////////////////////////////////////////////////////
206   // se_private_id.
207   /////////////////////////////////////////////////////////////////////////
208 
se_private_id()209   virtual Object_id se_private_id() const { return m_se_private_id; }
210 
set_se_private_id(Object_id se_private_id)211   virtual void set_se_private_id(Object_id se_private_id) {
212     m_se_private_id = se_private_id;
213   }
214 
215   /////////////////////////////////////////////////////////////////////////
216   // Storage engine attributes
217   /////////////////////////////////////////////////////////////////////////
218 
engine_attribute()219   LEX_CSTRING engine_attribute() const {
220     return lex_cstring_handle(m_engine_attribute);
221   }
222 
set_engine_attribute(LEX_CSTRING a)223   void set_engine_attribute(LEX_CSTRING a) {
224     m_engine_attribute.assign(a.str, a.length);
225   }
226 
secondary_engine_attribute()227   LEX_CSTRING secondary_engine_attribute() const {
228     return lex_cstring_handle(m_secondary_engine_attribute);
229   }
230 
set_secondary_engine_attribute(LEX_CSTRING a)231   void set_secondary_engine_attribute(LEX_CSTRING a) {
232     m_secondary_engine_attribute.assign(a.str, a.length);
233   }
234 
235   /////////////////////////////////////////////////////////////////////////
236   // Partition type
237   /////////////////////////////////////////////////////////////////////////
238 
partition_type()239   virtual enum_partition_type partition_type() const {
240     return m_partition_type;
241   }
242 
set_partition_type(enum_partition_type partition_type)243   virtual void set_partition_type(enum_partition_type partition_type) {
244     m_partition_type = partition_type;
245   }
246 
247   /////////////////////////////////////////////////////////////////////////
248   // default_partitioning
249   /////////////////////////////////////////////////////////////////////////
250 
default_partitioning()251   virtual enum_default_partitioning default_partitioning() const {
252     return m_default_partitioning;
253   }
254 
set_default_partitioning(enum_default_partitioning default_partitioning)255   virtual void set_default_partitioning(
256       enum_default_partitioning default_partitioning) {
257     m_default_partitioning = default_partitioning;
258   }
259 
260   /////////////////////////////////////////////////////////////////////////
261   // partition_expression
262   /////////////////////////////////////////////////////////////////////////
263 
partition_expression()264   virtual const String_type &partition_expression() const {
265     return m_partition_expression;
266   }
267 
set_partition_expression(const String_type & partition_expression)268   virtual void set_partition_expression(
269       const String_type &partition_expression) {
270     m_partition_expression = partition_expression;
271   }
272 
273   /////////////////////////////////////////////////////////////////////////
274   // partition_expression_utf8
275   /////////////////////////////////////////////////////////////////////////
276 
partition_expression_utf8()277   virtual const String_type &partition_expression_utf8() const {
278     return m_partition_expression_utf8;
279   }
280 
set_partition_expression_utf8(const String_type & partition_expression_utf8)281   virtual void set_partition_expression_utf8(
282       const String_type &partition_expression_utf8) {
283     m_partition_expression_utf8 = partition_expression_utf8;
284   }
285 
286   /////////////////////////////////////////////////////////////////////////
287   // subpartition_type
288   /////////////////////////////////////////////////////////////////////////
289 
subpartition_type()290   virtual enum_subpartition_type subpartition_type() const {
291     return m_subpartition_type;
292   }
293 
set_subpartition_type(enum_subpartition_type subpartition_type)294   virtual void set_subpartition_type(enum_subpartition_type subpartition_type) {
295     m_subpartition_type = subpartition_type;
296   }
297 
298   /////////////////////////////////////////////////////////////////////////
299   // default_subpartitioning
300   /////////////////////////////////////////////////////////////////////////
301 
default_subpartitioning()302   virtual enum_default_partitioning default_subpartitioning() const {
303     return m_default_subpartitioning;
304   }
305 
set_default_subpartitioning(enum_default_partitioning default_subpartitioning)306   virtual void set_default_subpartitioning(
307       enum_default_partitioning default_subpartitioning) {
308     m_default_subpartitioning = default_subpartitioning;
309   }
310 
311   /////////////////////////////////////////////////////////////////////////
312   // subpartition_expression
313   /////////////////////////////////////////////////////////////////////////
314 
subpartition_expression()315   virtual const String_type &subpartition_expression() const {
316     return m_subpartition_expression;
317   }
318 
set_subpartition_expression(const String_type & subpartition_expression)319   virtual void set_subpartition_expression(
320       const String_type &subpartition_expression) {
321     m_subpartition_expression = subpartition_expression;
322   }
323 
324   /////////////////////////////////////////////////////////////////////////
325   // subpartition_expression_utf8
326   /////////////////////////////////////////////////////////////////////////
327 
subpartition_expression_utf8()328   virtual const String_type &subpartition_expression_utf8() const {
329     return m_subpartition_expression_utf8;
330   }
331 
set_subpartition_expression_utf8(const String_type & subpartition_expression_utf8)332   virtual void set_subpartition_expression_utf8(
333       const String_type &subpartition_expression_utf8) {
334     m_subpartition_expression_utf8 = subpartition_expression_utf8;
335   }
336 
337   /////////////////////////////////////////////////////////////////////////
338   // Index collection.
339   /////////////////////////////////////////////////////////////////////////
340 
341   virtual Index *add_index();
342 
343   virtual Index *add_first_index();
344 
indexes()345   virtual const Index_collection &indexes() const { return m_indexes; }
346 
indexes()347   virtual Index_collection *indexes() { return &m_indexes; }
348 
get_index(Object_id index_id)349   const Index *get_index(Object_id index_id) const {
350     return const_cast<Table_impl *>(this)->get_index(index_id);
351   }
352 
353   Index *get_index(Object_id index_id);
354 
355   /////////////////////////////////////////////////////////////////////////
356   // Foreign key collection.
357   /////////////////////////////////////////////////////////////////////////
358 
359   virtual Foreign_key *add_foreign_key();
360 
foreign_keys()361   virtual const Foreign_key_collection &foreign_keys() const {
362     return m_foreign_keys;
363   }
364 
foreign_keys()365   virtual Foreign_key_collection *foreign_keys() { return &m_foreign_keys; }
366 
367   /////////////////////////////////////////////////////////////////////////
368   // Foreign key parent collection.
369   /////////////////////////////////////////////////////////////////////////
370 
371   virtual Foreign_key_parent *add_foreign_key_parent();
372 
373  private:
374   bool load_foreign_key_parents(Open_dictionary_tables_ctx *otx);
375 
376  public:
377   virtual bool reload_foreign_key_parents(THD *thd);
378 
foreign_key_parents()379   virtual const Foreign_key_parent_collection &foreign_key_parents() const {
380     return m_foreign_key_parents;
381   }
382 
383   /////////////////////////////////////////////////////////////////////////
384   // Partition collection.
385   /////////////////////////////////////////////////////////////////////////
386 
387   virtual Partition *add_partition();
388 
partitions()389   virtual const Partition_collection &partitions() const {
390     return m_partitions;
391   }
392 
partitions()393   virtual Partition_collection *partitions() { return &m_partitions; }
394 
leaf_partitions()395   virtual const Partition_leaf_vector &leaf_partitions() const {
396     return m_leaf_partitions;
397   }
398 
leaf_partitions()399   virtual Partition_leaf_vector *leaf_partitions() {
400     return &m_leaf_partitions;
401   }
402 
403   // non-virtual
add_leaf_partition(Partition * p)404   void add_leaf_partition(Partition *p) { m_leaf_partitions.push_back(p); }
405 
get_partition(Object_id partition_id)406   const Partition *get_partition(Object_id partition_id) const {
407     return const_cast<Table_impl *>(this)->get_partition(partition_id);
408   }
409 
410   Partition *get_partition(Object_id partition_id);
411 
412   Partition *get_partition(const String_type &name);
413 
414   // Fix "inherits ... via dominance" warnings
impl()415   virtual Entity_object_impl *impl() { return Entity_object_impl::impl(); }
impl()416   virtual const Entity_object_impl *impl() const {
417     return Entity_object_impl::impl();
418   }
id()419   virtual Object_id id() const { return Entity_object_impl::id(); }
is_persistent()420   virtual bool is_persistent() const {
421     return Entity_object_impl::is_persistent();
422   }
name()423   virtual const String_type &name() const { return Entity_object_impl::name(); }
set_name(const String_type & name)424   virtual void set_name(const String_type &name) {
425     Entity_object_impl::set_name(name);
426   }
schema_id()427   virtual Object_id schema_id() const {
428     return Abstract_table_impl::schema_id();
429   }
set_schema_id(Object_id schema_id)430   virtual void set_schema_id(Object_id schema_id) {
431     Abstract_table_impl::set_schema_id(schema_id);
432   }
mysql_version_id()433   virtual uint mysql_version_id() const {
434     return Abstract_table_impl::mysql_version_id();
435   }
options()436   virtual const Properties &options() const {
437     return Abstract_table_impl::options();
438   }
options()439   virtual Properties &options() { return Abstract_table_impl::options(); }
set_options(const Properties & options)440   virtual bool set_options(const Properties &options) {
441     return Abstract_table_impl::set_options(options);
442   }
set_options(const String_type & options_raw)443   virtual bool set_options(const String_type &options_raw) {
444     return Abstract_table_impl::set_options(options_raw);
445   }
created(bool convert_time)446   virtual ulonglong created(bool convert_time) const {
447     return Abstract_table_impl::created(convert_time);
448   }
set_created(ulonglong created)449   virtual void set_created(ulonglong created) {
450     Abstract_table_impl::set_created(created);
451   }
last_altered(bool convert_time)452   virtual ulonglong last_altered(bool convert_time) const {
453     return Abstract_table_impl::last_altered(convert_time);
454   }
set_last_altered(ulonglong last_altered)455   virtual void set_last_altered(ulonglong last_altered) {
456     Abstract_table_impl::set_last_altered(last_altered);
457   }
add_column()458   virtual Column *add_column() { return Abstract_table_impl::add_column(); }
columns()459   virtual const Column_collection &columns() const {
460     return Abstract_table_impl::columns();
461   }
columns()462   virtual Column_collection *columns() {
463     return Abstract_table_impl::columns();
464   }
get_column(Object_id column_id)465   const Column *get_column(Object_id column_id) const {
466     return Abstract_table_impl::get_column(column_id);
467   }
get_column(Object_id column_id)468   Column *get_column(Object_id column_id) {
469     return Abstract_table_impl::get_column(column_id);
470   }
get_column(const String_type & name)471   const Column *get_column(const String_type &name) const {
472     return Abstract_table_impl::get_column(name);
473   }
get_column(const String_type & name)474   Column *get_column(const String_type &name) {
475     return Abstract_table_impl::get_column(name);
476   }
update_aux_key(Aux_key * key)477   virtual bool update_aux_key(Aux_key *key) const {
478     return Table::update_aux_key(key);
479   }
hidden()480   virtual enum_hidden_type hidden() const {
481     return Abstract_table_impl::hidden();
482   }
set_hidden(enum_hidden_type hidden)483   virtual void set_hidden(enum_hidden_type hidden) {
484     Abstract_table_impl::set_hidden(hidden);
485   }
486 
487   /////////////////////////////////////////////////////////////////////////
488   // Trigger collection.
489   /////////////////////////////////////////////////////////////////////////
490 
has_trigger()491   virtual bool has_trigger() const { return (m_triggers.size() > 0); }
492 
triggers()493   virtual const Trigger_collection &triggers() const { return m_triggers; }
494 
triggers()495   virtual Trigger_collection *triggers() { return &m_triggers; }
496 
497   virtual void copy_triggers(const Table *tab_obj);
498 
499   virtual Trigger *add_trigger(Trigger::enum_action_timing at,
500                                Trigger::enum_event_type et);
501 
502   virtual const Trigger *get_trigger(const char *name) const;
503 
504   virtual Trigger *add_trigger_following(const Trigger *trigger,
505                                          Trigger::enum_action_timing at,
506                                          Trigger::enum_event_type et);
507 
508   virtual Trigger *add_trigger_preceding(const Trigger *trigger,
509                                          Trigger::enum_action_timing at,
510                                          Trigger::enum_event_type et);
511 
512   virtual void drop_trigger(const Trigger *trigger);
513 
514   virtual void drop_all_triggers();
515 
516  private:
517   uint get_max_action_order(Trigger::enum_action_timing at,
518                             Trigger::enum_event_type et) const;
519 
520   void reorder_action_order(Trigger::enum_action_timing at,
521                             Trigger::enum_event_type et);
522 
523   Trigger_impl *create_trigger();
524 
525  public:
526   /////////////////////////////////////////////////////////////////////////
527   // Check constraints.
528   /////////////////////////////////////////////////////////////////////////
529 
530   virtual Check_constraint *add_check_constraint();
531 
check_constraints()532   virtual const Check_constraint_collection &check_constraints() const {
533     return m_check_constraints;
534   }
535 
check_constraints()536   virtual Check_constraint_collection *check_constraints() {
537     return &m_check_constraints;
538   }
539 
540  private:
541   // Fields.
542 
543   Object_id m_se_private_id;
544 
545   String_type m_engine;
546   String_type m_comment;
547 
548   // Setting this to 0 means that every table will be checked by CHECK
549   // TABLE FOR UPGRADE once, even if it was created in this version.
550   // If we instead initialize to MYSQL_VERSION_ID, it will only run
551   // CHECK TABLE FOR UPGRADE after a real upgrade.
552   uint m_last_checked_for_upgrade_version_id = 0;
553   Properties_impl m_se_private_data;
554 
555   // SE-specific json attributes
556   dd::String_type m_engine_attribute;
557   dd::String_type m_secondary_engine_attribute;
558 
559   enum_row_format m_row_format;
560   bool m_is_temporary;
561 
562   // - Partitioning related fields.
563 
564   enum_partition_type m_partition_type;
565   String_type m_partition_expression;
566   String_type m_partition_expression_utf8;
567   enum_default_partitioning m_default_partitioning;
568 
569   enum_subpartition_type m_subpartition_type;
570   String_type m_subpartition_expression;
571   String_type m_subpartition_expression_utf8;
572   enum_default_partitioning m_default_subpartitioning;
573 
574   // References to tightly-coupled objects.
575 
576   Index_collection m_indexes;
577   Foreign_key_collection m_foreign_keys;
578   Foreign_key_parent_collection m_foreign_key_parents;
579   Partition_collection m_partitions;
580   Partition_leaf_vector m_leaf_partitions;
581   Trigger_collection m_triggers;
582   Check_constraint_collection m_check_constraints;
583 
584   // References to other objects.
585 
586   Object_id m_collation_id;
587   Object_id m_tablespace_id;
588 
589   Table_impl(const Table_impl &src);
clone()590   Table_impl *clone() const { return new Table_impl(*this); }
591 };
592 
593 ///////////////////////////////////////////////////////////////////////////
594 
595 }  // namespace dd
596 
597 #endif  // DD__TABLE_IMPL_INCLUDED
598