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