1 /* Copyright (c) 2010, 2021, Oracle and/or its affiliates.
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-1301, USA */
22 
23 /**
24   @file storage/perfschema/table_esms_by_account_by_event_name.cc
25   Table EVENTS_STATEMENTS_SUMMARY_BY_ACCOUNT_BY_EVENT_NAME (implementation).
26 */
27 
28 #include "my_global.h"
29 #include "my_thread.h"
30 #include "pfs_instr_class.h"
31 #include "pfs_column_types.h"
32 #include "pfs_column_values.h"
33 #include "table_esms_by_account_by_event_name.h"
34 #include "pfs_global.h"
35 #include "pfs_visitor.h"
36 #include "pfs_buffer_container.h"
37 #include "field.h"
38 
39 THR_LOCK table_esms_by_account_by_event_name::m_table_lock;
40 
41 static const TABLE_FIELD_TYPE field_types[]=
42 {
43   {
44     { C_STRING_WITH_LEN("USER") },
45     { C_STRING_WITH_LEN("char(" USERNAME_CHAR_LENGTH_STR ")") },
46     { NULL, 0}
47   },
48   {
49     { C_STRING_WITH_LEN("HOST") },
50     { C_STRING_WITH_LEN("char(60)") },
51     { NULL, 0}
52   },
53   {
54     { C_STRING_WITH_LEN("EVENT_NAME") },
55     { C_STRING_WITH_LEN("varchar(128)") },
56     { NULL, 0}
57   },
58   {
59     { C_STRING_WITH_LEN("COUNT_STAR") },
60     { C_STRING_WITH_LEN("bigint(20)") },
61     { NULL, 0}
62   },
63   {
64     { C_STRING_WITH_LEN("SUM_TIMER_WAIT") },
65     { C_STRING_WITH_LEN("bigint(20)") },
66     { NULL, 0}
67   },
68   {
69     { C_STRING_WITH_LEN("MIN_TIMER_WAIT") },
70     { C_STRING_WITH_LEN("bigint(20)") },
71     { NULL, 0}
72   },
73   {
74     { C_STRING_WITH_LEN("AVG_TIMER_WAIT") },
75     { C_STRING_WITH_LEN("bigint(20)") },
76     { NULL, 0}
77   },
78   {
79     { C_STRING_WITH_LEN("MAX_TIMER_WAIT") },
80     { C_STRING_WITH_LEN("bigint(20)") },
81     { NULL, 0}
82   },
83   {
84     { C_STRING_WITH_LEN("SUM_LOCK_TIME") },
85     { C_STRING_WITH_LEN("bigint(20)") },
86     { NULL, 0}
87   },
88   {
89     { C_STRING_WITH_LEN("SUM_ERRORS") },
90     { C_STRING_WITH_LEN("bigint(20)") },
91     { NULL, 0}
92   },
93   {
94     { C_STRING_WITH_LEN("SUM_WARNINGS") },
95     { C_STRING_WITH_LEN("bigint(20)") },
96     { NULL, 0}
97   },
98   {
99     { C_STRING_WITH_LEN("SUM_ROWS_AFFECTED") },
100     { C_STRING_WITH_LEN("bigint(20)") },
101     { NULL, 0}
102   },
103   {
104     { C_STRING_WITH_LEN("SUM_ROWS_SENT") },
105     { C_STRING_WITH_LEN("bigint(20)") },
106     { NULL, 0}
107   },
108   {
109     { C_STRING_WITH_LEN("SUM_ROWS_EXAMINED") },
110     { C_STRING_WITH_LEN("bigint(20)") },
111     { NULL, 0}
112   },
113   {
114     { C_STRING_WITH_LEN("SUM_CREATED_TMP_DISK_TABLES") },
115     { C_STRING_WITH_LEN("bigint(20)") },
116     { NULL, 0}
117   },
118   {
119     { C_STRING_WITH_LEN("SUM_CREATED_TMP_TABLES") },
120     { C_STRING_WITH_LEN("bigint(20)") },
121     { NULL, 0}
122   },
123   {
124     { C_STRING_WITH_LEN("SUM_SELECT_FULL_JOIN") },
125     { C_STRING_WITH_LEN("bigint(20)") },
126     { NULL, 0}
127   },
128   {
129     { C_STRING_WITH_LEN("SUM_SELECT_FULL_RANGE_JOIN") },
130     { C_STRING_WITH_LEN("bigint(20)") },
131     { NULL, 0}
132   },
133   {
134     { C_STRING_WITH_LEN("SUM_SELECT_RANGE") },
135     { C_STRING_WITH_LEN("bigint(20)") },
136     { NULL, 0}
137   },
138   {
139     { C_STRING_WITH_LEN("SUM_SELECT_RANGE_CHECK") },
140     { C_STRING_WITH_LEN("bigint(20)") },
141     { NULL, 0}
142   },
143   {
144     { C_STRING_WITH_LEN("SUM_SELECT_SCAN") },
145     { C_STRING_WITH_LEN("bigint(20)") },
146     { NULL, 0}
147   },
148   {
149     { C_STRING_WITH_LEN("SUM_SORT_MERGE_PASSES") },
150     { C_STRING_WITH_LEN("bigint(20)") },
151     { NULL, 0}
152   },
153   {
154     { C_STRING_WITH_LEN("SUM_SORT_RANGE") },
155     { C_STRING_WITH_LEN("bigint(20)") },
156     { NULL, 0}
157   },
158   {
159     { C_STRING_WITH_LEN("SUM_SORT_ROWS") },
160     { C_STRING_WITH_LEN("bigint(20)") },
161     { NULL, 0}
162   },
163   {
164     { C_STRING_WITH_LEN("SUM_SORT_SCAN") },
165     { C_STRING_WITH_LEN("bigint(20)") },
166     { NULL, 0}
167   },
168   {
169     { C_STRING_WITH_LEN("SUM_NO_INDEX_USED") },
170     { C_STRING_WITH_LEN("bigint(20)") },
171     { NULL, 0}
172   },
173   {
174     { C_STRING_WITH_LEN("SUM_NO_GOOD_INDEX_USED") },
175     { C_STRING_WITH_LEN("bigint(20)") },
176     { NULL, 0}
177   }
178 };
179 
180 TABLE_FIELD_DEF
181 table_esms_by_account_by_event_name::m_field_def=
182 { 27, field_types };
183 
184 PFS_engine_table_share
185 table_esms_by_account_by_event_name::m_share=
186 {
187   { C_STRING_WITH_LEN("events_statements_summary_by_account_by_event_name") },
188   &pfs_truncatable_acl,
189   table_esms_by_account_by_event_name::create,
190   NULL, /* write_row */
191   table_esms_by_account_by_event_name::delete_all_rows,
192   table_esms_by_account_by_event_name::get_row_count,
193   sizeof(pos_esms_by_account_by_event_name),
194   &m_table_lock,
195   &m_field_def,
196   false, /* checked */
197   false  /* perpetual */
198 };
199 
200 PFS_engine_table*
create(void)201 table_esms_by_account_by_event_name::create(void)
202 {
203   return new table_esms_by_account_by_event_name();
204 }
205 
206 int
delete_all_rows(void)207 table_esms_by_account_by_event_name::delete_all_rows(void)
208 {
209   reset_events_statements_by_thread();
210   reset_events_statements_by_account();
211   return 0;
212 }
213 
214 ha_rows
get_row_count(void)215 table_esms_by_account_by_event_name::get_row_count(void)
216 {
217   return global_account_container.get_row_count() * statement_class_max;
218 }
219 
table_esms_by_account_by_event_name()220 table_esms_by_account_by_event_name::table_esms_by_account_by_event_name()
221   : PFS_engine_table(&m_share, &m_pos),
222     m_row_exists(false), m_pos(), m_next_pos()
223 {}
224 
reset_position(void)225 void table_esms_by_account_by_event_name::reset_position(void)
226 {
227   m_pos.reset();
228   m_next_pos.reset();
229 }
230 
rnd_init(bool scan)231 int table_esms_by_account_by_event_name::rnd_init(bool scan)
232 {
233   m_normalizer= time_normalizer::get(statement_timer);
234   return 0;
235 }
236 
rnd_next(void)237 int table_esms_by_account_by_event_name::rnd_next(void)
238 {
239   PFS_account *account;
240   PFS_statement_class *statement_class;
241   bool has_more_account= true;
242 
243   for (m_pos.set_at(&m_next_pos);
244        has_more_account;
245        m_pos.next_account())
246   {
247     account= global_account_container.get(m_pos.m_index_1, & has_more_account);
248     if (account != NULL)
249     {
250       statement_class= find_statement_class(m_pos.m_index_2);
251       if (statement_class)
252       {
253         make_row(account, statement_class);
254         m_next_pos.set_after(&m_pos);
255         return 0;
256       }
257     }
258   }
259 
260   return HA_ERR_END_OF_FILE;
261 }
262 
263 int
rnd_pos(const void * pos)264 table_esms_by_account_by_event_name::rnd_pos(const void *pos)
265 {
266   PFS_account *account;
267   PFS_statement_class *statement_class;
268 
269   set_position(pos);
270 
271   account= global_account_container.get(m_pos.m_index_1);
272   if (account != NULL)
273   {
274     statement_class= find_statement_class(m_pos.m_index_2);
275     if (statement_class)
276     {
277       make_row(account, statement_class);
278       return 0;
279     }
280   }
281 
282   return HA_ERR_RECORD_DELETED;
283 }
284 
285 void table_esms_by_account_by_event_name
make_row(PFS_account * account,PFS_statement_class * klass)286 ::make_row(PFS_account *account, PFS_statement_class *klass)
287 {
288   pfs_optimistic_state lock;
289   m_row_exists= false;
290 
291   if (klass->is_mutable())
292     return;
293 
294   account->m_lock.begin_optimistic_lock(&lock);
295 
296   if (m_row.m_account.make_row(account))
297     return;
298 
299   m_row.m_event_name.make_row(klass);
300 
301   PFS_connection_statement_visitor visitor(klass);
302   PFS_connection_iterator::visit_account(account,
303                                          true,  /* threads */
304                                          false, /* THDs */
305                                          & visitor);
306 
307   if (! account->m_lock.end_optimistic_lock(&lock))
308     return;
309 
310   m_row_exists= true;
311   m_row.m_stat.set(m_normalizer, & visitor.m_stat);
312 }
313 
314 int table_esms_by_account_by_event_name
read_row_values(TABLE * table,unsigned char * buf,Field ** fields,bool read_all)315 ::read_row_values(TABLE *table, unsigned char *buf, Field **fields,
316                   bool read_all)
317 {
318   Field *f;
319 
320   if (unlikely(! m_row_exists))
321     return HA_ERR_RECORD_DELETED;
322 
323   /* Set the null bits */
324   assert(table->s->null_bytes == 1);
325   buf[0]= 0;
326 
327   for (; (f= *fields) ; fields++)
328   {
329     if (read_all || bitmap_is_set(table->read_set, f->field_index))
330     {
331       switch(f->field_index)
332       {
333       case 0: /* USER */
334       case 1: /* HOST */
335         m_row.m_account.set_field(f->field_index, f);
336         break;
337       case 2: /* EVENT_NAME */
338         m_row.m_event_name.set_field(f);
339         break;
340       default: /* 3, ... COUNT/SUM/MIN/AVG/MAX */
341         m_row.m_stat.set_field(f->field_index - 3, f);
342         break;
343       }
344     }
345   }
346 
347   return 0;
348 }
349 
350