1 /* Copyright (c) 2008, 2011, 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 Foundation,
21   51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA */
22 
23 #ifndef PFS_ENGINE_TABLE_H
24 #define PFS_ENGINE_TABLE_H
25 
26 #include "sql_acl.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 class Field;
34 struct PFS_engine_table_share;
35 struct time_normalizer;
36 
37 /**
38   @addtogroup Performance_schema_engine
39   @{
40 */
41 
42 /**
43   An abstract PERFORMANCE_SCHEMA table.
44   Every table implemented in the performance schema schema and storage engine
45   derives from this class.
46 */
47 class PFS_engine_table
48 {
49 public:
50   static const PFS_engine_table_share*
51     find_engine_table_share(const char *name);
52 
53   int read_row(TABLE *table, unsigned char *buf, Field **fields);
54 
55   int update_row(TABLE *table, const unsigned char *old_buf,
56                  const unsigned char *new_buf, Field **fields);
57 
58   /**
59     Delete a row from this table.
60     @param table Table handle
61     @param buf the row buffer to delete
62     @param fields Table fields
63     @return 0 on success
64   */
65   int delete_row(TABLE *table, const unsigned char *buf, Field **fields);
66 
67   /** Initialize table scan. */
rnd_init(bool scan)68   virtual int rnd_init(bool scan){return 0;};
69 
70   /** Fetch the next row in this cursor. */
71   virtual int rnd_next(void)= 0;
72   /**
73     Fetch a row by position.
74     @param pos              position to fetch
75   */
76   virtual int rnd_pos(const void *pos)= 0;
77 
78   void get_position(void *ref);
79   void set_position(const void *ref);
80   /** Reset the cursor position to the beginning of the table. */
81   virtual void reset_position(void)= 0;
82 
83   /** Get the normalizer and class type for the current row. */
84   void get_normalizer(PFS_instr_class *instr_class);
85 
86   /** Destructor. */
~PFS_engine_table()87   virtual ~PFS_engine_table()
88   {}
89 
90   /**
91     Helper, assign a value to a ulong field.
92     @param f the field to set
93     @param value the value to assign
94   */
95   static void set_field_ulong(Field *f, ulong value);
96   /**
97     Helper, assign a value to a ulonglong field.
98     @param f the field to set
99     @param value the value to assign
100   */
101   static void set_field_ulonglong(Field *f, ulonglong value);
102   /**
103     Helper, assign a value to a char utf8 field.
104     @param f the field to set
105     @param str the string to assign
106     @param len the length of the string to assign
107   */
108   static void set_field_char_utf8(Field *f, const char *str, uint len);
109   /**
110     Helper, assign a value to a varchar utf8 field.
111     @param f the field to set
112     @param str the string to assign
113     @param len the length of the string to assign
114   */
115   static void set_field_varchar_utf8(Field *f, const char *str, uint len);
116   /**
117     Helper, assign a value to a longtext utf8 field.
118     @param f the field to set
119     @param str the string to assign
120     @param len the length of the string to assign
121   */
122   static void set_field_longtext_utf8(Field *f, const char *str, uint len);
123   /**
124     Helper, assign a value to an enum field.
125     @param f the field to set
126     @param value the value to assign
127   */
128   static void set_field_enum(Field *f, ulonglong value);
129   /**
130     Helper, assign a value to a timestamp field.
131     @param f the field to set
132     @param value the value to assign
133   */
134   static void set_field_timestamp(Field *f, ulonglong value);
135   /**
136     Helper, read a value from an enum field.
137     @param f the field to read
138     @return the field value
139   */
140   static ulonglong get_field_enum(Field *f);
141   /**
142     Helper, read a value from a char utf8 field.
143     @param f the field to read
144     @param[out] val the field value
145     @return the field value
146   */
147   static String *get_field_char_utf8(Field *f, String *val);
148   /**
149     Helper, read a value from a varchar utf8 field.
150     @param f the field to read
151     @param[out] val the field value
152     @return the field value
153   */
154   static String *get_field_varchar_utf8(Field *f, String *val);
155 
156 protected:
157   /**
158     Read the current row values.
159     @param table            Table handle
160     @param buf              row buffer
161     @param fields           Table fields
162     @param read_all         true if all columns are read.
163   */
164   virtual int read_row_values(TABLE *table, unsigned char *buf,
165                               Field **fields, bool read_all)= 0;
166 
167   /**
168     Update the current row values.
169     @param table            Table handle
170     @param old_buf          old row buffer
171     @param new_buf          new row buffer
172     @param fields           Table fields
173   */
174   virtual int update_row_values(TABLE *table, const unsigned char *old_buf,
175                                 const unsigned char *new_buf, Field **fields);
176 
177   /**
178     Delete a row.
179     @param table            Table handle
180     @param buf              Row buffer
181     @param fields           Table fields
182   */
183   virtual int delete_row_values(TABLE *table, const unsigned char *buf,
184                                 Field **fields);
185 
186   /**
187     Constructor.
188     @param share            table share
189     @param pos              address of the m_pos position member
190   */
PFS_engine_table(const PFS_engine_table_share * share,void * pos)191   PFS_engine_table(const PFS_engine_table_share *share, void *pos)
192     : m_share_ptr(share), m_pos_ptr(pos),
193       m_normalizer(NULL), m_class_type(PFS_CLASS_NONE)
194   {}
195 
196   /** Table share. */
197   const PFS_engine_table_share *m_share_ptr;
198   /** Opaque pointer to the m_pos position of this cursor. */
199   void *m_pos_ptr;
200   /** Current normalizer */
201   time_normalizer *m_normalizer;
202   /** Current class type */
203   enum PFS_class_type m_class_type;
204 };
205 
206 /** Callback to open a table. */
207 typedef PFS_engine_table* (*pfs_open_table_t)(void);
208 /** Callback to write a row. */
209 typedef int (*pfs_write_row_t)(TABLE *table,
210                                unsigned char *buf, Field **fields);
211 /** Callback to delete all rows. */
212 typedef int (*pfs_delete_all_rows_t)(void);
213 /** Callback to get a row count. */
214 typedef ha_rows (*pfs_get_row_count_t)(void);
215 
216 /**
217   A PERFORMANCE_SCHEMA table share.
218   This data is shared by all the table handles opened on the same table.
219 */
220 struct PFS_engine_table_share
221 {
222   static void init_all_locks(void);
223   static void delete_all_locks(void);
224   /** Get the row count. */
225   ha_rows get_row_count(void) const;
226   /** Write a row. */
227   int write_row(TABLE *table, unsigned char *buf, Field **fields) const;
228 
229   /** Table name. */
230   LEX_STRING m_name;
231   /** Table ACL. */
232   const ACL_internal_table_access *m_acl;
233   /** Open table function. */
234   pfs_open_table_t m_open_table;
235   /** Write row function. */
236   pfs_write_row_t m_write_row;
237   /** Delete all rows function. */
238   pfs_delete_all_rows_t m_delete_all_rows;
239   /** Get rows count function. */
240   pfs_get_row_count_t m_get_row_count;
241   /**
242     Number or records.
243     This number does not need to be precise,
244     it is used by the optimizer to decide if the table
245     has 0, 1, or many records.
246   */
247   ha_rows m_records;
248   /** Length of the m_pos position structure. */
249   uint m_ref_length;
250   /** The lock, stored on behalf of the SQL layer. */
251   THR_LOCK *m_thr_lock_ptr;
252   /** Table definition. */
253   LEX_STRING sql;
254 };
255 
256 /**
257   Privileges for read only tables.
258   The only operation allowed is SELECT.
259 */
260 class PFS_readonly_acl : public ACL_internal_table_access
261 {
262 public:
PFS_readonly_acl()263   PFS_readonly_acl()
264   {}
265 
~PFS_readonly_acl()266   ~PFS_readonly_acl()
267   {}
268 
269   virtual ACL_internal_access_result check(ulong want_access, ulong *save_priv) const;
270 };
271 
272 /** Singleton instance of PFS_readonly_acl. */
273 extern PFS_readonly_acl pfs_readonly_acl;
274 
275 /**
276   Privileges for truncatable tables.
277   Operations allowed are SELECT and TRUNCATE.
278 */
279 class PFS_truncatable_acl : public ACL_internal_table_access
280 {
281 public:
PFS_truncatable_acl()282   PFS_truncatable_acl()
283   {}
284 
~PFS_truncatable_acl()285   ~PFS_truncatable_acl()
286   {}
287 
288   ACL_internal_access_result check(ulong want_access, ulong *save_priv) const;
289 };
290 
291 /** Singleton instance of PFS_truncatable_acl. */
292 extern PFS_truncatable_acl pfs_truncatable_acl;
293 
294 /**
295   Privileges for updatable tables.
296   Operations allowed are SELECT and UPDATE.
297 */
298 class PFS_updatable_acl : public ACL_internal_table_access
299 {
300 public:
PFS_updatable_acl()301   PFS_updatable_acl()
302   {}
303 
~PFS_updatable_acl()304   ~PFS_updatable_acl()
305   {}
306 
307   ACL_internal_access_result check(ulong want_access, ulong *save_priv) const;
308 };
309 
310 /** Singleton instance of PFS_updatable_acl. */
311 extern PFS_updatable_acl pfs_updatable_acl;
312 
313 /**
314   Privileges for editable tables.
315   Operations allowed are SELECT, INSERT, UPDATE, DELETE and TRUNCATE.
316 */
317 class PFS_editable_acl : public ACL_internal_table_access
318 {
319 public:
PFS_editable_acl()320   PFS_editable_acl()
321   {}
322 
~PFS_editable_acl()323   ~PFS_editable_acl()
324   {}
325 
326   ACL_internal_access_result check(ulong want_access, ulong *save_priv) const;
327 };
328 
329 /** Singleton instance of PFS_editable_acl. */
330 extern PFS_editable_acl pfs_editable_acl;
331 
332 /**
333   Privileges for unknown tables.
334 */
335 class PFS_unknown_acl : public ACL_internal_table_access
336 {
337 public:
PFS_unknown_acl()338   PFS_unknown_acl()
339   {}
340 
~PFS_unknown_acl()341   ~PFS_unknown_acl()
342   {}
343 
344   ACL_internal_access_result check(ulong want_access, ulong *save_priv) const;
345 };
346 
347 /** Singleton instance of PFS_unknown_acl. */
348 extern PFS_unknown_acl pfs_unknown_acl;
349 
350 /** Position of a cursor, for simple iterations. */
351 struct PFS_simple_index
352 {
353   /** Current row index. */
354   uint m_index;
355 
356   /**
357     Constructor.
358     @param index the index initial value.
359   */
PFS_simple_indexPFS_simple_index360   PFS_simple_index(uint index)
361     : m_index(index)
362   {}
363 
364   /**
365     Set this index at a given position.
366     @param other a position
367   */
set_atPFS_simple_index368   void set_at(const struct PFS_simple_index *other)
369   { m_index= other->m_index; }
370 
371   /**
372     Set this index after a given position.
373     @param other a position
374   */
set_afterPFS_simple_index375   void set_after(const struct PFS_simple_index *other)
376   { m_index= other->m_index + 1; }
377 
378   /** Set this index to the next record. */
nextPFS_simple_index379   void next(void)
380   { m_index++; }
381 };
382 
383 /** Position of a double cursor, for iterations using 2 nested loops. */
384 struct PFS_double_index
385 {
386   /** Outer index. */
387   uint m_index_1;
388   /** Current index within index_1. */
389   uint m_index_2;
390 
391   /**
392     Constructor.
393     @param index_1 the first index initial value.
394     @param index_2 the second index initial value.
395   */
PFS_double_indexPFS_double_index396   PFS_double_index(uint index_1, uint index_2)
397     : m_index_1(index_1), m_index_2(index_2)
398   {}
399 
400   /**
401     Set this index at a given position.
402     @param other a position
403   */
set_atPFS_double_index404   void set_at(const struct PFS_double_index *other)
405   {
406     m_index_1= other->m_index_1;
407     m_index_2= other->m_index_2;
408   }
409 
410   /**
411     Set this index after a given position.
412     @param other a position
413   */
set_afterPFS_double_index414   void set_after(const struct PFS_double_index *other)
415   {
416     m_index_1= other->m_index_1;
417     m_index_2= other->m_index_2 + 1;
418   }
419 };
420 
421 /** Position of a triple cursor, for iterations using 3 nested loops. */
422 struct PFS_triple_index
423 {
424   /** Outer index. */
425   uint m_index_1;
426   /** Current index within index_1. */
427   uint m_index_2;
428   /** Current index within index_2. */
429   uint m_index_3;
430 
431   /**
432     Constructor.
433     @param index_1 the first index initial value.
434     @param index_2 the second index initial value.
435     @param index_3 the third index initial value.
436   */
PFS_triple_indexPFS_triple_index437   PFS_triple_index(uint index_1, uint index_2, uint index_3)
438     : m_index_1(index_1), m_index_2(index_2), m_index_3(index_3)
439   {}
440 
441   /**
442     Set this index at a given position.
443     @param other a position
444   */
set_atPFS_triple_index445   void set_at(const struct PFS_triple_index *other)
446   {
447     m_index_1= other->m_index_1;
448     m_index_2= other->m_index_2;
449     m_index_3= other->m_index_3;
450   }
451 
452   /**
453     Set this index after a given position.
454     @param other a position
455   */
set_afterPFS_triple_index456   void set_after(const struct PFS_triple_index *other)
457   {
458     m_index_1= other->m_index_1;
459     m_index_2= other->m_index_2;
460     m_index_3= other->m_index_3 + 1;
461   }
462 };
463 
464 bool pfs_show_status(handlerton *hton, THD *thd,
465                      stat_print_fn *print, enum ha_stat_type stat);
466 
467 int pfs_discover_table_names(handlerton *hton, LEX_CSTRING *db,
468                              MY_DIR *dir,
469                              handlerton::discovered_list *result);
470 
471 /** @} */
472 #endif
473