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"
26class Field;
27struct PFS_engine_table_share;
28struct 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*/
40class PFS_engine_table
41{
42public:
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
149protected:
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. */
200typedef PFS_engine_table* (*pfs_open_table_t)(void);
201/** Callback to write a row. */
202typedef int (*pfs_write_row_t)(TABLE *table,
203 unsigned char *buf, Field **fields);
204/** Callback to delete all rows. */
205typedef int (*pfs_delete_all_rows_t)(void);
206/** Callback to get a row count. */
207typedef 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*/
213struct 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*/
253class PFS_readonly_acl : public ACL_internal_table_access
254{
255public:
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. */
266extern PFS_readonly_acl pfs_readonly_acl;
267
268/**
269 Privileges for truncatable tables.
270 Operations allowed are SELECT and TRUNCATE.
271*/
272class PFS_truncatable_acl : public ACL_internal_table_access
273{
274public:
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. */
285extern PFS_truncatable_acl pfs_truncatable_acl;
286
287/**
288 Privileges for updatable tables.
289 Operations allowed are SELECT and UPDATE.
290*/
291class PFS_updatable_acl : public ACL_internal_table_access
292{
293public:
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. */
304extern PFS_updatable_acl pfs_updatable_acl;
305
306/**
307 Privileges for editable tables.
308 Operations allowed are SELECT, INSERT, UPDATE, DELETE and TRUNCATE.
309*/
310class PFS_editable_acl : public ACL_internal_table_access
311{
312public:
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. */
323extern PFS_editable_acl pfs_editable_acl;
324
325/**
326 Privileges for unknown tables.
327*/
328class PFS_unknown_acl : public ACL_internal_table_access
329{
330public:
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. */
341extern PFS_unknown_acl pfs_unknown_acl;
342
343/** Position of a cursor, for simple iterations. */
344struct 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. */
377struct 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. */
415struct 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
457bool pfs_show_status(handlerton *hton, THD *thd,
458 stat_print_fn *print, enum ha_stat_type stat);
459
460int pfs_discover_table_names(handlerton *hton, LEX_CSTRING *db,
461 MY_DIR *dir,
462 handlerton::discovered_list *result);
463
464/** @} */
465#endif
466