1 /* Copyright (c) 2008, 2010, 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 as published by
5   the Free Software Foundation; version 2 of the License.
6 
7   This program is distributed in the hope that it will be useful,
8   but WITHOUT ANY WARRANTY; without even the implied warranty of
9   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10   GNU General Public License for more details.
11 
12   You should have received a copy of the GNU General Public License
13   along with this program; if not, write to the Free Software Foundation,
14   51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
15 
16 #ifndef PFS_ENGINE_TABLE_H
17 #define PFS_ENGINE_TABLE_H
18 
19 #include "sql_acl.h"                            /* struct ACL_* */
20 /**
21   @file storage/perfschema/pfs_engine_table.h
22   Performance schema tables (declarations).
23 */
24 
25 class Field;
26 struct PFS_engine_table_share;
27 
28 /**
29   @addtogroup Performance_schema_engine
30   @{
31 */
32 
33 /**
34   An abstract PERFORMANCE_SCHEMA table.
35   Every table implemented in the performance schema schema and storage engine
36   derives from this class.
37 */
38 class PFS_engine_table
39 {
40 public:
41   static const PFS_engine_table_share*
42     find_engine_table_share(const char *name);
43 
44   int read_row(TABLE *table, unsigned char *buf, Field **fields);
45 
46   int update_row(TABLE *table, const unsigned char *old_buf,
47                  unsigned char *new_buf, Field **fields);
48 
49   /** Fetch the next row in this cursor. */
50   virtual int rnd_next(void)= 0;
51   /**
52     Fetch a row by position.
53     @param pos              position to fetch
54   */
55   virtual int rnd_pos(const void *pos)= 0;
56 
57   void get_position(void *ref);
58   void set_position(const void *ref);
59   virtual void reset_position(void)= 0;
60 
61   /** Destructor. */
~PFS_engine_table()62   virtual ~PFS_engine_table()
63   {}
64 
65 protected:
66   /**
67     Read the current row values.
68     @param table            Table handle
69     @param buf              row buffer
70     @param fields           Table fields
71     @param read_all         true if all columns are read.
72   */
73   virtual int read_row_values(TABLE *table, unsigned char *buf,
74                               Field **fields, bool read_all)= 0;
75 
76   /**
77     Update the current row values.
78     @param table            Table handle
79     @param old_buf          old row buffer
80     @param new_buf          new row buffer
81     @param fields           Table fields
82   */
83   virtual int update_row_values(TABLE *table, const unsigned char *old_buf,
84                                 unsigned char *new_buf, Field **fields);
85 
86   /**
87     Constructor.
88     @param share            table share
89     @param pos              address of the m_pos position member
90   */
PFS_engine_table(const PFS_engine_table_share * share,void * pos)91   PFS_engine_table(const PFS_engine_table_share *share, void *pos)
92     : m_share_ptr(share), m_pos_ptr(pos)
93   {}
94 
95   void set_field_ulong(Field *f, ulong value);
96   void set_field_ulonglong(Field *f, ulonglong value);
97   void set_field_varchar_utf8(Field *f, const char* str, uint len);
98   void set_field_enum(Field *f, ulonglong value);
99 
100   ulonglong get_field_enum(Field *f);
101 
102   /** Table share. */
103   const PFS_engine_table_share *m_share_ptr;
104   /** Opaque pointer to the m_pos position of this cursor. */
105   void *m_pos_ptr;
106 };
107 
108 /** Callback to open a table. */
109 typedef PFS_engine_table* (*pfs_open_table_t)(void);
110 /** Callback to write a row. */
111 typedef int (*pfs_write_row_t)(TABLE *table,
112                                unsigned char *buf, Field **fields);
113 /** Callback to delete all rows. */
114 typedef int (*pfs_delete_all_rows_t)(void);
115 
116 /**
117   A PERFORMANCE_SCHEMA table share.
118   This data is shared by all the table handles opened on the same table.
119 */
120 struct PFS_engine_table_share
121 {
122   static void check_all_tables(THD *thd);
123   void check_one_table(THD *thd);
124   static void init_all_locks(void);
125   static void delete_all_locks(void);
126 
127   /** Table name. */
128   LEX_STRING m_name;
129   /** Table ACL. */
130   const ACL_internal_table_access *m_acl;
131   /** Open table function. */
132   pfs_open_table_t m_open_table;
133   /** Write row function. */
134   pfs_write_row_t m_write_row;
135   /** Delete all rows function. */
136   pfs_delete_all_rows_t m_delete_all_rows;
137   /**
138     Number or records.
139     This number does not need to be precise,
140     it is used by the optimizer to decide if the table
141     has 0, 1, or many records.
142   */
143   ha_rows m_records;
144   /** Length of the m_pos position structure. */
145   uint m_ref_length;
146   /** The lock, stored on behalf of the SQL layer. */
147   THR_LOCK *m_thr_lock_ptr;
148   /** Table fields definition. */
149   TABLE_FIELD_DEF *m_field_def;
150   /** Schema integrity flag. */
151   bool m_checked;
152 };
153 
154 class PFS_readonly_acl : public ACL_internal_table_access
155 {
156 public:
PFS_readonly_acl()157   PFS_readonly_acl()
158   {}
159 
~PFS_readonly_acl()160   ~PFS_readonly_acl()
161   {}
162 
163   ACL_internal_access_result check(ulong want_access, ulong *save_priv) const;
164 };
165 
166 extern PFS_readonly_acl pfs_readonly_acl;
167 
168 class PFS_truncatable_acl : public ACL_internal_table_access
169 {
170 public:
PFS_truncatable_acl()171   PFS_truncatable_acl()
172   {}
173 
~PFS_truncatable_acl()174   ~PFS_truncatable_acl()
175   {}
176 
177   ACL_internal_access_result check(ulong want_access, ulong *save_priv) const;
178 };
179 
180 extern PFS_truncatable_acl pfs_truncatable_acl;
181 
182 class PFS_updatable_acl : public ACL_internal_table_access
183 {
184 public:
PFS_updatable_acl()185   PFS_updatable_acl()
186   {}
187 
~PFS_updatable_acl()188   ~PFS_updatable_acl()
189   {}
190 
191   ACL_internal_access_result check(ulong want_access, ulong *save_priv) const;
192 };
193 
194 extern PFS_updatable_acl pfs_updatable_acl;
195 
196 class PFS_editable_acl : public ACL_internal_table_access
197 {
198 public:
PFS_editable_acl()199   PFS_editable_acl()
200   {}
201 
~PFS_editable_acl()202   ~PFS_editable_acl()
203   {}
204 
205   ACL_internal_access_result check(ulong want_access, ulong *save_priv) const;
206 };
207 
208 extern PFS_editable_acl pfs_editable_acl;
209 
210 class PFS_unknown_acl : public ACL_internal_table_access
211 {
212 public:
PFS_unknown_acl()213   PFS_unknown_acl()
214   {}
215 
~PFS_unknown_acl()216   ~PFS_unknown_acl()
217   {}
218 
219   ACL_internal_access_result check(ulong want_access, ulong *save_priv) const;
220 };
221 
222 extern PFS_unknown_acl pfs_unknown_acl;
223 
224 /** Position of a cursor, for simple iterations. */
225 struct PFS_simple_index
226 {
227   /** Current row index. */
228   uint m_index;
229 
PFS_simple_indexPFS_simple_index230   PFS_simple_index(uint index)
231     : m_index(index)
232   {}
233 
set_atPFS_simple_index234   void set_at(const struct PFS_simple_index *other)
235   { m_index= other->m_index; }
236 
set_afterPFS_simple_index237   void set_after(const struct PFS_simple_index *other)
238   { m_index= other->m_index + 1; }
239 
nextPFS_simple_index240   void next(void)
241   { m_index++; }
242 };
243 
244 struct PFS_double_index
245 {
246   /** Outer index. */
247   uint m_index_1;
248   /** Current index within index_1. */
249   uint m_index_2;
250 
PFS_double_indexPFS_double_index251   PFS_double_index(uint index_1, uint index_2)
252     : m_index_1(index_1), m_index_2(index_2)
253   {}
254 
set_atPFS_double_index255   void set_at(const struct PFS_double_index *other)
256   {
257     m_index_1= other->m_index_1;
258     m_index_2= other->m_index_2;
259   }
260 
set_afterPFS_double_index261   void set_after(const struct PFS_double_index *other)
262   {
263     m_index_1= other->m_index_1;
264     m_index_2= other->m_index_2 + 1;
265   }
266 };
267 
268 struct PFS_triple_index
269 {
270   /** Outer index. */
271   uint m_index_1;
272   /** Current index within index_1. */
273   uint m_index_2;
274   /** Current index within index_2. */
275   uint m_index_3;
276 
PFS_triple_indexPFS_triple_index277   PFS_triple_index(uint index_1, uint index_2, uint index_3)
278     : m_index_1(index_1), m_index_2(index_2), m_index_3(index_3)
279   {}
280 
set_atPFS_triple_index281   void set_at(const struct PFS_triple_index *other)
282   {
283     m_index_1= other->m_index_1;
284     m_index_2= other->m_index_2;
285     m_index_3= other->m_index_3;
286   }
287 
set_afterPFS_triple_index288   void set_after(const struct PFS_triple_index *other)
289   {
290     m_index_1= other->m_index_1;
291     m_index_2= other->m_index_2;
292     m_index_3= other->m_index_3 + 1;
293   }
294 };
295 
296 struct PFS_instrument_view_constants
297 {
298   static const uint VIEW_MUTEX= 1;
299   static const uint VIEW_RWLOCK= 2;
300   static const uint VIEW_COND= 3;
301   static const uint VIEW_FILE= 4;
302 };
303 
304 struct PFS_object_view_constants
305 {
306   static const uint VIEW_TABLE= 1;
307   static const uint VIEW_EVENT= 2;
308   static const uint VIEW_PROCEDURE= 3;
309   static const uint VIEW_FUNCTION= 4;
310 };
311 
312 bool pfs_show_status(handlerton *hton, THD *thd,
313                      stat_print_fn *print, enum ha_stat_type stat);
314 
315 /** @} */
316 #endif
317