1 /* Copyright (c) 2008, 2021, Oracle and/or its affiliates. 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 Foundation, 21 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */ 22 23 #ifndef PFS_ENGINE_TABLE_H 24 #define PFS_ENGINE_TABLE_H 25 26 #include "auth_common.h" /* struct ACL_* */ 27 /** 28 @file storage/perfschema/pfs_engine_table.h 29 Performance schema tables (declarations). 30 */ 31 32 #include "pfs_instr_class.h" 33 extern thread_local_key_t THR_PFS_VG; // global_variables 34 extern thread_local_key_t THR_PFS_SV; // session_variables 35 extern thread_local_key_t THR_PFS_VBT; // variables_by_thread 36 extern thread_local_key_t THR_PFS_SG; // global_status 37 extern thread_local_key_t THR_PFS_SS; // session_status 38 extern thread_local_key_t THR_PFS_SBT; // status_by_thread 39 extern thread_local_key_t THR_PFS_SBU; // status_by_user 40 extern thread_local_key_t THR_PFS_SBH; // status_by_host 41 extern thread_local_key_t THR_PFS_SBA; // status_by_account 42 43 class Field; 44 struct PFS_engine_table_share; 45 struct time_normalizer; 46 47 /** 48 @addtogroup Performance_schema_engine 49 @{ 50 */ 51 52 /** 53 Store and retrieve table state information during a query. 54 */ 55 class PFS_table_context 56 { 57 public: 58 PFS_table_context(ulonglong current_version, bool restore, thread_local_key_t key); 59 PFS_table_context(ulonglong current_version, ulong map_size, bool restore, thread_local_key_t key); 60 ~PFS_table_context(void); 61 62 bool initialize(void); is_initialized(void)63 bool is_initialized(void) { return m_initialized; } current_version(void)64 ulonglong current_version(void) { return m_current_version; } last_version(void)65 ulonglong last_version(void) { return m_last_version; } versions_match(void)66 bool versions_match(void) { return m_last_version == m_current_version; } 67 void set_item(ulong n); 68 bool is_item_set(ulong n); 69 thread_local_key_t m_thr_key; 70 71 private: 72 ulonglong m_current_version; 73 ulonglong m_last_version; 74 ulong *m_map; 75 ulong m_map_size; 76 ulong m_word_size; 77 bool m_restore; 78 bool m_initialized; 79 ulong m_last_item; 80 }; 81 82 /** 83 An abstract PERFORMANCE_SCHEMA table. 84 Every table implemented in the performance schema schema and storage engine 85 derives from this class. 86 */ 87 class PFS_engine_table 88 { 89 public: 90 static const PFS_engine_table_share* 91 find_engine_table_share(const char *name); 92 93 int read_row(TABLE *table, unsigned char *buf, Field **fields); 94 95 int update_row(TABLE *table, const unsigned char *old_buf, 96 unsigned char *new_buf, Field **fields); 97 98 /** 99 Delete a row from this table. 100 @param table Table handle 101 @param buf the row buffer to delete 102 @param fields Table fields 103 @return 0 on success 104 */ 105 int delete_row(TABLE *table, const unsigned char *buf, Field **fields); 106 107 /** Initialize table scan. */ rnd_init(bool scan)108 virtual int rnd_init(bool scan){return 0;}; 109 110 /** Fetch the next row in this cursor. */ 111 virtual int rnd_next(void)= 0; 112 /** 113 Fetch a row by position. 114 @param pos position to fetch 115 */ 116 virtual int rnd_pos(const void *pos)= 0; 117 118 void get_position(void *ref); 119 void set_position(const void *ref); 120 /** Reset the cursor position to the beginning of the table. */ 121 virtual void reset_position(void)= 0; 122 123 /** Get the normalizer and class type for the current row. */ 124 void get_normalizer(PFS_instr_class *instr_class); 125 126 /** Destructor. */ ~PFS_engine_table()127 virtual ~PFS_engine_table() 128 {} 129 130 /** 131 Helper, assign a value to a long field. 132 @param f the field to set 133 @param value the value to assign 134 */ 135 static void set_field_long(Field *f, long value); 136 /** 137 Helper, assign a value to a ulong field. 138 @param f the field to set 139 @param value the value to assign 140 */ 141 static void set_field_ulong(Field *f, ulong value); 142 /** 143 Helper, assign a value to a longlong field. 144 @param f the field to set 145 @param value the value to assign 146 */ 147 static void set_field_longlong(Field *f, longlong value); 148 /** 149 Helper, assign a value to a ulonglong field. 150 @param f the field to set 151 @param value the value to assign 152 */ 153 static void set_field_ulonglong(Field *f, ulonglong value); 154 /** 155 Helper, assign a value to a char utf8 field. 156 @param f the field to set 157 @param str the string to assign 158 @param len the length of the string to assign 159 */ 160 static void set_field_char_utf8(Field *f, const char *str, uint len); 161 /** 162 Helper, assign a value to a varchar utf8 field. 163 @param f the field to set 164 @param cs the string character set 165 @param str the string to assign 166 @param len the length of the string to assign 167 */ 168 static void set_field_varchar(Field *f, const CHARSET_INFO *cs, const char *str, uint len); 169 /** 170 Helper, assign a value to a varchar utf8 field. 171 @param f the field to set 172 @param str the string to assign 173 @param len the length of the string to assign 174 */ 175 static void set_field_varchar_utf8(Field *f, const char *str, uint len); 176 /** 177 Helper, assign a value to a longtext utf8 field. 178 @param f the field to set 179 @param str the string to assign 180 @param len the length of the string to assign 181 */ 182 static void set_field_longtext_utf8(Field *f, const char *str, uint len); 183 /** 184 Helper, assign a value to a blob field. 185 @param f the field to set 186 @param val the value to assign 187 @param len the length of the string to assign 188 */ 189 static void set_field_blob(Field *f, const char *val, uint len); 190 /** 191 Helper, assign a value to an enum field. 192 @param f the field to set 193 @param value the value to assign 194 */ 195 static void set_field_enum(Field *f, ulonglong value); 196 /** 197 Helper, assign a value to a timestamp field. 198 @param f the field to set 199 @param value the value to assign 200 */ 201 static void set_field_timestamp(Field *f, ulonglong value); 202 /** 203 Helper, assign a value to a double field. 204 @param f the field to set 205 @param value the value to assign 206 */ 207 static void set_field_double(Field *f, double value); 208 /** 209 Helper, read a value from an enum field. 210 @param f the field to read 211 @return the field value 212 */ 213 static ulonglong get_field_enum(Field *f); 214 /** 215 Helper, read a value from a char utf8 field. 216 @param f the field to read 217 @param[out] val the field value 218 @return the field value 219 */ 220 static String *get_field_char_utf8(Field *f, String *val); 221 /** 222 Helper, read a value from a varchar utf8 field. 223 @param f the field to read 224 @param[out] val the field value 225 @return the field value 226 */ 227 static String *get_field_varchar_utf8(Field *f, String *val); 228 229 protected: 230 /** 231 Read the current row values. 232 @param table Table handle 233 @param buf row buffer 234 @param fields Table fields 235 @param read_all true if all columns are read. 236 */ 237 virtual int read_row_values(TABLE *table, unsigned char *buf, 238 Field **fields, bool read_all)= 0; 239 240 /** 241 Update the current row values. 242 @param table Table handle 243 @param old_buf old row buffer 244 @param new_buf new row buffer 245 @param fields Table fields 246 */ 247 virtual int update_row_values(TABLE *table, const unsigned char *old_buf, 248 unsigned char *new_buf, Field **fields); 249 250 /** 251 Delete a row. 252 @param table Table handle 253 @param buf Row buffer 254 @param fields Table fields 255 */ 256 virtual int delete_row_values(TABLE *table, const unsigned char *buf, 257 Field **fields); 258 /** 259 Constructor. 260 @param share table share 261 @param pos address of the m_pos position member 262 */ PFS_engine_table(const PFS_engine_table_share * share,void * pos)263 PFS_engine_table(const PFS_engine_table_share *share, void *pos) 264 : m_share_ptr(share), m_pos_ptr(pos), 265 m_normalizer(NULL), m_class_type(PFS_CLASS_NONE) 266 {} 267 268 /** Table share. */ 269 const PFS_engine_table_share *m_share_ptr; 270 /** Opaque pointer to the m_pos position of this cursor. */ 271 void *m_pos_ptr; 272 /** Current normalizer */ 273 time_normalizer *m_normalizer; 274 /** Current class type */ 275 enum PFS_class_type m_class_type; 276 }; 277 278 /** Callback to open a table. */ 279 typedef PFS_engine_table* (*pfs_open_table_t)(void); 280 /** Callback to write a row. */ 281 typedef int (*pfs_write_row_t)(TABLE *table, 282 unsigned char *buf, Field **fields); 283 /** Callback to delete all rows. */ 284 typedef int (*pfs_delete_all_rows_t)(void); 285 /** Callback to get a row count. */ 286 typedef ha_rows (*pfs_get_row_count_t)(void); 287 288 /** 289 A PERFORMANCE_SCHEMA table share. 290 This data is shared by all the table handles opened on the same table. 291 */ 292 struct PFS_engine_table_share 293 { 294 static void check_all_tables(THD *thd); 295 void check_one_table(THD *thd); 296 static void init_all_locks(void); 297 static void delete_all_locks(void); 298 /** Get the row count. */ 299 ha_rows get_row_count(void) const; 300 /** Write a row. */ 301 int write_row(TABLE *table, unsigned char *buf, Field **fields) const; 302 303 /** Table name. */ 304 LEX_STRING m_name; 305 /** Table ACL. */ 306 const ACL_internal_table_access *m_acl; 307 /** Open table function. */ 308 pfs_open_table_t m_open_table; 309 /** Write row function. */ 310 pfs_write_row_t m_write_row; 311 /** Delete all rows function. */ 312 pfs_delete_all_rows_t m_delete_all_rows; 313 /** Get rows count function. */ 314 pfs_get_row_count_t m_get_row_count; 315 /** Length of the m_pos position structure. */ 316 uint m_ref_length; 317 /** The lock, stored on behalf of the SQL layer. */ 318 THR_LOCK *m_thr_lock_ptr; 319 /** Table fields definition. */ 320 TABLE_FIELD_DEF *m_field_def; 321 /** Schema integrity flag. */ 322 bool m_checked; 323 /** Table is available even if the Performance Schema is disabled. */ 324 bool m_perpetual; 325 }; 326 327 /** 328 Privileges for read only tables. 329 The only operation allowed is SELECT. 330 */ 331 class PFS_readonly_acl : public ACL_internal_table_access 332 { 333 public: PFS_readonly_acl()334 PFS_readonly_acl() 335 {} 336 ~PFS_readonly_acl()337 ~PFS_readonly_acl() 338 {} 339 340 virtual ACL_internal_access_result check(ulong want_access, ulong *save_priv) const; 341 }; 342 343 /** Singleton instance of PFS_readonly_acl. */ 344 extern PFS_readonly_acl pfs_readonly_acl; 345 346 /** 347 Privileges for truncatable tables. 348 Operations allowed are SELECT and TRUNCATE. 349 */ 350 class PFS_truncatable_acl : public ACL_internal_table_access 351 { 352 public: PFS_truncatable_acl()353 PFS_truncatable_acl() 354 {} 355 ~PFS_truncatable_acl()356 ~PFS_truncatable_acl() 357 {} 358 359 ACL_internal_access_result check(ulong want_access, ulong *save_priv) const; 360 }; 361 362 /** Singleton instance of PFS_truncatable_acl. */ 363 extern PFS_truncatable_acl pfs_truncatable_acl; 364 365 /** 366 Privileges for updatable tables. 367 Operations allowed are SELECT and UPDATE. 368 */ 369 class PFS_updatable_acl : public ACL_internal_table_access 370 { 371 public: PFS_updatable_acl()372 PFS_updatable_acl() 373 {} 374 ~PFS_updatable_acl()375 ~PFS_updatable_acl() 376 {} 377 378 ACL_internal_access_result check(ulong want_access, ulong *save_priv) const; 379 }; 380 381 /** Singleton instance of PFS_updatable_acl. */ 382 extern PFS_updatable_acl pfs_updatable_acl; 383 384 /** 385 Privileges for editable tables. 386 Operations allowed are SELECT, INSERT, UPDATE, DELETE and TRUNCATE. 387 */ 388 class PFS_editable_acl : public ACL_internal_table_access 389 { 390 public: PFS_editable_acl()391 PFS_editable_acl() 392 {} 393 ~PFS_editable_acl()394 ~PFS_editable_acl() 395 {} 396 397 ACL_internal_access_result check(ulong want_access, ulong *save_priv) const; 398 }; 399 400 /** Singleton instance of PFS_editable_acl. */ 401 extern PFS_editable_acl pfs_editable_acl; 402 403 /** 404 Privileges for unknown tables. 405 */ 406 class PFS_unknown_acl : public ACL_internal_table_access 407 { 408 public: PFS_unknown_acl()409 PFS_unknown_acl() 410 {} 411 ~PFS_unknown_acl()412 ~PFS_unknown_acl() 413 {} 414 415 ACL_internal_access_result check(ulong want_access, ulong *save_priv) const; 416 }; 417 418 /** Singleton instance of PFS_unknown_acl. */ 419 extern PFS_unknown_acl pfs_unknown_acl; 420 421 422 /** 423 Privileges for world readable tables. 424 */ 425 class PFS_readonly_world_acl : public PFS_readonly_acl 426 { 427 public: PFS_readonly_world_acl()428 PFS_readonly_world_acl() 429 {} 430 ~PFS_readonly_world_acl()431 ~PFS_readonly_world_acl() 432 {} 433 virtual ACL_internal_access_result check(ulong want_access, ulong *save_priv) const; 434 }; 435 436 437 /** Singleton instance of PFS_readonly_world_acl */ 438 extern PFS_readonly_world_acl pfs_readonly_world_acl; 439 440 441 /** 442 Privileges for world readable truncatable tables. 443 */ 444 class PFS_truncatable_world_acl : public PFS_truncatable_acl 445 { 446 public: PFS_truncatable_world_acl()447 PFS_truncatable_world_acl() 448 {} 449 ~PFS_truncatable_world_acl()450 ~PFS_truncatable_world_acl() 451 {} 452 virtual ACL_internal_access_result check(ulong want_access, ulong *save_priv) const; 453 }; 454 455 456 /** Singleton instance of PFS_readonly_world_acl */ 457 extern PFS_truncatable_world_acl pfs_truncatable_world_acl; 458 459 460 /** Position of a cursor, for simple iterations. */ 461 struct PFS_simple_index 462 { 463 /** Current row index. */ 464 uint m_index; 465 466 /** 467 Constructor. 468 @param index the index initial value. 469 */ PFS_simple_indexPFS_simple_index470 PFS_simple_index(uint index) 471 : m_index(index) 472 {} 473 474 /** 475 Set this index at a given position. 476 @param index an index 477 */ set_atPFS_simple_index478 void set_at(uint index) 479 { m_index= index; } 480 481 /** 482 Set this index at a given position. 483 @param other a position 484 */ set_atPFS_simple_index485 void set_at(const struct PFS_simple_index *other) 486 { m_index= other->m_index; } 487 488 /** 489 Set this index after a given position. 490 @param other a position 491 */ set_afterPFS_simple_index492 void set_after(const struct PFS_simple_index *other) 493 { m_index= other->m_index + 1; } 494 495 /** Set this index to the next record. */ nextPFS_simple_index496 void next(void) 497 { m_index++; } 498 }; 499 500 /** Position of a double cursor, for iterations using 2 nested loops. */ 501 struct PFS_double_index 502 { 503 /** Outer index. */ 504 uint m_index_1; 505 /** Current index within index_1. */ 506 uint m_index_2; 507 508 /** 509 Constructor. 510 @param index_1 the first index initial value. 511 @param index_2 the second index initial value. 512 */ PFS_double_indexPFS_double_index513 PFS_double_index(uint index_1, uint index_2) 514 : m_index_1(index_1), m_index_2(index_2) 515 {} 516 517 /** 518 Set this index at a given position. 519 */ set_atPFS_double_index520 void set_at(uint index_1, uint index_2) 521 { 522 m_index_1= index_1; 523 m_index_2= index_2; 524 } 525 526 /** 527 Set this index at a given position. 528 @param other a position 529 */ set_atPFS_double_index530 void set_at(const struct PFS_double_index *other) 531 { 532 m_index_1= other->m_index_1; 533 m_index_2= other->m_index_2; 534 } 535 536 /** 537 Set this index after a given position. 538 @param other a position 539 */ set_afterPFS_double_index540 void set_after(const struct PFS_double_index *other) 541 { 542 m_index_1= other->m_index_1; 543 m_index_2= other->m_index_2 + 1; 544 } 545 }; 546 547 /** Position of a triple cursor, for iterations using 3 nested loops. */ 548 struct PFS_triple_index 549 { 550 /** Outer index. */ 551 uint m_index_1; 552 /** Current index within index_1. */ 553 uint m_index_2; 554 /** Current index within index_2. */ 555 uint m_index_3; 556 557 /** 558 Constructor. 559 @param index_1 the first index initial value. 560 @param index_2 the second index initial value. 561 @param index_3 the third index initial value. 562 */ PFS_triple_indexPFS_triple_index563 PFS_triple_index(uint index_1, uint index_2, uint index_3) 564 : m_index_1(index_1), m_index_2(index_2), m_index_3(index_3) 565 {} 566 567 /** 568 Set this index at a given position. 569 */ set_atPFS_triple_index570 void set_at(uint index_1, uint index_2, uint index_3) 571 { 572 m_index_1= index_1; 573 m_index_2= index_2; 574 m_index_3= index_3; 575 } 576 577 /** 578 Set this index at a given position. 579 @param other a position 580 */ set_atPFS_triple_index581 void set_at(const struct PFS_triple_index *other) 582 { 583 m_index_1= other->m_index_1; 584 m_index_2= other->m_index_2; 585 m_index_3= other->m_index_3; 586 } 587 588 /** 589 Set this index after a given position. 590 @param other a position 591 */ set_afterPFS_triple_index592 void set_after(const struct PFS_triple_index *other) 593 { 594 m_index_1= other->m_index_1; 595 m_index_2= other->m_index_2; 596 m_index_3= other->m_index_3 + 1; 597 } 598 }; 599 600 bool pfs_show_status(handlerton *hton, THD *thd, 601 stat_print_fn *print, enum ha_stat_type stat); 602 603 /** @} */ 604 #endif 605