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