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