1 /* Copyright (c) 2010, 2015, 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
21   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335  USA */
22 
23 /**
24   @file storage/perfschema/table_helper.cc
25   Performance schema table helpers (implementation).
26 */
27 
28 #include "my_global.h"
29 #include "my_pthread.h"
30 #include "pfs_engine_table.h"
31 #include "table_helper.h"
32 #include "pfs_host.h"
33 #include "pfs_user.h"
34 #include "pfs_account.h"
35 #include "pfs_instr.h"
36 
make_row(PFS_host * pfs)37 int PFS_host_row::make_row(PFS_host *pfs)
38 {
39   m_hostname_length= pfs->m_hostname_length;
40   if (m_hostname_length > sizeof(m_hostname))
41     return 1;
42   if (m_hostname_length > 0)
43     memcpy(m_hostname, pfs->m_hostname, sizeof(m_hostname));
44   return 0;
45 }
46 
set_field(Field * f)47 void PFS_host_row::set_field(Field *f)
48 {
49   if (m_hostname_length > 0)
50     PFS_engine_table::set_field_char_utf8(f, m_hostname, m_hostname_length);
51   else
52     f->set_null();
53 }
54 
make_row(PFS_user * pfs)55 int PFS_user_row::make_row(PFS_user *pfs)
56 {
57   m_username_length= pfs->m_username_length;
58   if (m_username_length > sizeof(m_username))
59     return 1;
60   if (m_username_length > 0)
61     memcpy(m_username, pfs->m_username, sizeof(m_username));
62   return 0;
63 }
64 
set_field(Field * f)65 void PFS_user_row::set_field(Field *f)
66 {
67   if (m_username_length > 0)
68     PFS_engine_table::set_field_char_utf8(f, m_username, m_username_length);
69   else
70     f->set_null();
71 }
72 
make_row(PFS_account * pfs)73 int PFS_account_row::make_row(PFS_account *pfs)
74 {
75   m_username_length= pfs->m_username_length;
76   if (m_username_length > sizeof(m_username))
77     return 1;
78   if (m_username_length > 0)
79     memcpy(m_username, pfs->m_username, sizeof(m_username));
80 
81   m_hostname_length= pfs->m_hostname_length;
82   if (m_hostname_length > sizeof(m_hostname))
83     return 1;
84   if (m_hostname_length > 0)
85     memcpy(m_hostname, pfs->m_hostname, sizeof(m_hostname));
86 
87   return 0;
88 }
89 
set_field(uint index,Field * f)90 void PFS_account_row::set_field(uint index, Field *f)
91 {
92   switch (index)
93   {
94     case 0: /* USER */
95       if (m_username_length > 0)
96         PFS_engine_table::set_field_char_utf8(f, m_username, m_username_length);
97       else
98         f->set_null();
99       break;
100     case 1: /* HOST */
101       if (m_hostname_length > 0)
102         PFS_engine_table::set_field_char_utf8(f, m_hostname, m_hostname_length);
103       else
104         f->set_null();
105       break;
106     default:
107       DBUG_ASSERT(false);
108       break;
109   }
110 }
111 
make_row(PFS_statements_digest_stat * pfs)112 int PFS_digest_row::make_row(PFS_statements_digest_stat* pfs)
113 {
114   m_schema_name_length= pfs->m_digest_key.m_schema_name_length;
115   if (m_schema_name_length > sizeof(m_schema_name))
116     m_schema_name_length= 0;
117   if (m_schema_name_length > 0)
118     memcpy(m_schema_name, pfs->m_digest_key.m_schema_name, m_schema_name_length);
119 
120   size_t safe_byte_count= pfs->m_digest_storage.m_byte_count;
121   if (safe_byte_count > pfs_max_digest_length)
122     safe_byte_count= 0;
123 
124   /*
125     "0" value for byte_count indicates special entry i.e. aggregated
126     stats at index 0 of statements_digest_stat_array. So do not calculate
127     digest/digest_text as it should always be "NULL".
128   */
129   if (safe_byte_count > 0)
130   {
131     /*
132       Calculate digest from MD5 HASH collected to be shown as
133       DIGEST in this row.
134     */
135     MD5_HASH_TO_STRING(pfs->m_digest_storage.m_md5, m_digest);
136     m_digest_length= MD5_HASH_TO_STRING_LENGTH;
137 
138     /*
139       Calculate digest_text information from the token array collected
140       to be shown as DIGEST_TEXT column.
141     */
142     compute_digest_text(&pfs->m_digest_storage, &m_digest_text);
143 
144     if (m_digest_text.length() == 0)
145       m_digest_length= 0;
146   }
147   else
148   {
149     m_digest_length= 0;
150     m_digest_text.length(0);
151   }
152 
153   return 0;
154 }
155 
set_field(uint index,Field * f)156 void PFS_digest_row::set_field(uint index, Field *f)
157 {
158   switch (index)
159   {
160     case 0: /* SCHEMA_NAME */
161       if (m_schema_name_length > 0)
162         PFS_engine_table::set_field_varchar_utf8(f, m_schema_name,
163                                                  m_schema_name_length);
164       else
165         f->set_null();
166       break;
167     case 1: /* DIGEST */
168       if (m_digest_length > 0)
169         PFS_engine_table::set_field_varchar_utf8(f, m_digest,
170                                                  m_digest_length);
171       else
172         f->set_null();
173       break;
174     case 2: /* DIGEST_TEXT */
175       if (m_digest_text.length() > 0)
176         PFS_engine_table::set_field_longtext_utf8(f, m_digest_text.ptr(),
177                                                   m_digest_text.length());
178       else
179         f->set_null();
180       break;
181     default:
182       DBUG_ASSERT(false);
183       break;
184   }
185 }
186 
make_row(PFS_table_share * pfs)187 int PFS_object_row::make_row(PFS_table_share *pfs)
188 {
189   m_object_type= pfs->get_object_type();
190 
191   m_schema_name_length= pfs->m_schema_name_length;
192   if (m_schema_name_length > sizeof(m_schema_name))
193     return 1;
194   if (m_schema_name_length > 0)
195     memcpy(m_schema_name, pfs->m_schema_name, sizeof(m_schema_name));
196 
197   m_object_name_length= pfs->m_table_name_length;
198   if (m_object_name_length > sizeof(m_object_name))
199     return 1;
200   if (m_object_name_length > 0)
201     memcpy(m_object_name, pfs->m_table_name, sizeof(m_object_name));
202 
203   return 0;
204 }
205 
set_field(uint index,Field * f)206 void PFS_object_row::set_field(uint index, Field *f)
207 {
208   switch(index)
209   {
210     case 0: /* OBJECT_TYPE */
211       set_field_object_type(f, m_object_type);
212       break;
213     case 1: /* SCHEMA_NAME */
214       PFS_engine_table::set_field_varchar_utf8(f, m_schema_name, m_schema_name_length);
215       break;
216     case 2: /* OBJECT_NAME */
217       PFS_engine_table::set_field_varchar_utf8(f, m_object_name, m_object_name_length);
218       break;
219     default:
220       DBUG_ASSERT(false);
221   }
222 }
223 
make_row(PFS_table_share * pfs,uint table_index)224 int PFS_index_row::make_row(PFS_table_share *pfs, uint table_index)
225 {
226   if (m_object_row.make_row(pfs))
227     return 1;
228 
229   if (table_index < MAX_INDEXES)
230   {
231     PFS_table_key *key= &pfs->m_keys[table_index];
232     m_index_name_length= key->m_name_length;
233     if (m_index_name_length > sizeof(m_index_name))
234       return 1;
235     memcpy(m_index_name, key->m_name, sizeof(m_index_name));
236   }
237   else
238     m_index_name_length= 0;
239 
240   return 0;
241 }
242 
set_field(uint index,Field * f)243 void PFS_index_row::set_field(uint index, Field *f)
244 {
245   switch(index)
246   {
247     case 0: /* OBJECT_TYPE */
248     case 1: /* SCHEMA_NAME */
249     case 2: /* OBJECT_NAME */
250       m_object_row.set_field(index, f);
251       break;
252     case 3: /* INDEX_NAME */
253       if (m_index_name_length > 0)
254         PFS_engine_table::set_field_varchar_utf8(f, m_index_name, m_index_name_length);
255       else
256         f->set_null();
257       break;
258     default:
259       DBUG_ASSERT(false);
260   }
261 }
262 
set_field(uint index,Field * f)263 void PFS_statement_stat_row::set_field(uint index, Field *f)
264 {
265   switch (index)
266   {
267     case 0: /* COUNT_STAR */
268     case 1: /* SUM_TIMER_WAIT */
269     case 2: /* MIN_TIMER_WAIT */
270     case 3: /* AVG_TIMER_WAIT */
271     case 4: /* MAX_TIMER_WAIT */
272       m_timer1_row.set_field(index, f);
273       break;
274     case 5: /* SUM_LOCK_TIME */
275       PFS_engine_table::set_field_ulonglong(f, m_lock_time);
276       break;
277     case 6: /* SUM_ERRORS */
278       PFS_engine_table::set_field_ulonglong(f, m_error_count);
279       break;
280     case 7: /* SUM_WARNINGS */
281       PFS_engine_table::set_field_ulonglong(f, m_warning_count);
282       break;
283     case 8: /* SUM_ROWS_AFFECTED */
284       PFS_engine_table::set_field_ulonglong(f, m_rows_affected);
285       break;
286     case 9: /* SUM_ROWS_SENT */
287       PFS_engine_table::set_field_ulonglong(f, m_rows_sent);
288       break;
289     case 10: /* SUM_ROWS_EXAMINED */
290       PFS_engine_table::set_field_ulonglong(f, m_rows_examined);
291       break;
292     case 11: /* SUM_CREATED_TMP_DISK_TABLES */
293       PFS_engine_table::set_field_ulonglong(f, m_created_tmp_disk_tables);
294       break;
295     case 12: /* SUM_CREATED_TMP_TABLES */
296       PFS_engine_table::set_field_ulonglong(f, m_created_tmp_tables);
297       break;
298     case 13: /* SUM_SELECT_FULL_JOIN */
299       PFS_engine_table::set_field_ulonglong(f, m_select_full_join);
300       break;
301     case 14: /* SUM_SELECT_FULL_RANGE_JOIN */
302       PFS_engine_table::set_field_ulonglong(f, m_select_full_range_join);
303       break;
304     case 15: /* SUM_SELECT_RANGE */
305       PFS_engine_table::set_field_ulonglong(f, m_select_range);
306       break;
307     case 16: /* SUM_SELECT_RANGE_CHECK */
308       PFS_engine_table::set_field_ulonglong(f, m_select_range_check);
309       break;
310     case 17: /* SUM_SELECT_SCAN */
311       PFS_engine_table::set_field_ulonglong(f, m_select_scan);
312       break;
313     case 18: /* SUM_SORT_MERGE_PASSES */
314       PFS_engine_table::set_field_ulonglong(f, m_sort_merge_passes);
315       break;
316     case 19: /* SUM_SORT_RANGE */
317       PFS_engine_table::set_field_ulonglong(f, m_sort_range);
318       break;
319     case 20: /* SUM_SORT_ROWS */
320       PFS_engine_table::set_field_ulonglong(f, m_sort_rows);
321       break;
322     case 21: /* SUM_SORT_SCAN */
323       PFS_engine_table::set_field_ulonglong(f, m_sort_scan);
324       break;
325     case 22: /* SUM_NO_INDEX_USED */
326       PFS_engine_table::set_field_ulonglong(f, m_no_index_used);
327       break;
328     case 23: /* SUM_NO_GOOD_INDEX_USED */
329       PFS_engine_table::set_field_ulonglong(f, m_no_good_index_used);
330       break;
331     default:
332       DBUG_ASSERT(false);
333       break;
334   }
335 }
336 
set_field(uint index,Field * f)337 void PFS_connection_stat_row::set_field(uint index, Field *f)
338 {
339   switch (index)
340   {
341     case 0: /* CURRENT_CONNECTIONS */
342       PFS_engine_table::set_field_ulonglong(f, m_current_connections);
343       break;
344     case 1: /* TOTAL_CONNECTIONS */
345       PFS_engine_table::set_field_ulonglong(f, m_total_connections);
346       break;
347     default:
348       DBUG_ASSERT(false);
349       break;
350   }
351 }
352 
set_field_object_type(Field * f,enum_object_type object_type)353 void set_field_object_type(Field *f, enum_object_type object_type)
354 {
355   switch (object_type)
356   {
357   case OBJECT_TYPE_TABLE:
358     PFS_engine_table::set_field_varchar_utf8(f, "TABLE", 5);
359     break;
360   case OBJECT_TYPE_TEMPORARY_TABLE:
361     PFS_engine_table::set_field_varchar_utf8(f, "TEMPORARY TABLE", 15);
362     break;
363   default:
364     DBUG_ASSERT(false);
365   }
366 }
367 
368