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