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_esgs_by_user_by_event_name.cc
25   Table EVENTS_STAGES_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_esgs_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_esgs_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 
80 TABLE_FIELD_DEF
81 table_esgs_by_user_by_event_name::m_field_def=
82 { 7, field_types };
83 
84 PFS_engine_table_share
85 table_esgs_by_user_by_event_name::m_share=
86 {
87   { C_STRING_WITH_LEN("events_stages_summary_by_user_by_event_name") },
88   &pfs_truncatable_acl,
89   table_esgs_by_user_by_event_name::create,
90   NULL, /* write_row */
91   table_esgs_by_user_by_event_name::delete_all_rows,
92   table_esgs_by_user_by_event_name::get_row_count,
93   sizeof(pos_esgs_by_user_by_event_name),
94   &m_table_lock,
95   &m_field_def,
96   false, /* checked */
97   false  /* perpetual */
98 };
99 
100 PFS_engine_table*
create(void)101 table_esgs_by_user_by_event_name::create(void)
102 {
103   return new table_esgs_by_user_by_event_name();
104 }
105 
106 int
delete_all_rows(void)107 table_esgs_by_user_by_event_name::delete_all_rows(void)
108 {
109   reset_events_stages_by_thread();
110   reset_events_stages_by_account();
111   reset_events_stages_by_user();
112   return 0;
113 }
114 
115 ha_rows
get_row_count(void)116 table_esgs_by_user_by_event_name::get_row_count(void)
117 {
118   return global_user_container.get_row_count() * stage_class_max;
119 }
120 
table_esgs_by_user_by_event_name()121 table_esgs_by_user_by_event_name::table_esgs_by_user_by_event_name()
122   : PFS_engine_table(&m_share, &m_pos),
123     m_row_exists(false), m_pos(), m_next_pos()
124 {}
125 
reset_position(void)126 void table_esgs_by_user_by_event_name::reset_position(void)
127 {
128   m_pos.reset();
129   m_next_pos.reset();
130 }
131 
rnd_init(bool scan)132 int table_esgs_by_user_by_event_name::rnd_init(bool scan)
133 {
134   m_normalizer= time_normalizer::get(stage_timer);
135   return 0;
136 }
137 
rnd_next(void)138 int table_esgs_by_user_by_event_name::rnd_next(void)
139 {
140   PFS_user *user;
141   PFS_stage_class *stage_class;
142   bool has_more_user= true;
143 
144   for (m_pos.set_at(&m_next_pos);
145        has_more_user;
146        m_pos.next_user())
147   {
148     user= global_user_container.get(m_pos.m_index_1, & has_more_user);
149     if (user != NULL)
150     {
151       stage_class= find_stage_class(m_pos.m_index_2);
152       if (stage_class)
153       {
154         make_row(user, stage_class);
155         m_next_pos.set_after(&m_pos);
156         return 0;
157       }
158     }
159   }
160 
161   return HA_ERR_END_OF_FILE;
162 }
163 
164 int
rnd_pos(const void * pos)165 table_esgs_by_user_by_event_name::rnd_pos(const void *pos)
166 {
167   PFS_user *user;
168   PFS_stage_class *stage_class;
169 
170   set_position(pos);
171 
172   user= global_user_container.get(m_pos.m_index_1);
173   if (user != NULL)
174   {
175     stage_class= find_stage_class(m_pos.m_index_2);
176     if (stage_class)
177     {
178       make_row(user, stage_class);
179       return 0;
180     }
181   }
182 
183   return HA_ERR_RECORD_DELETED;
184 }
185 
186 void table_esgs_by_user_by_event_name
make_row(PFS_user * user,PFS_stage_class * klass)187 ::make_row(PFS_user *user, PFS_stage_class *klass)
188 {
189   pfs_optimistic_state lock;
190   m_row_exists= false;
191 
192   user->m_lock.begin_optimistic_lock(&lock);
193 
194   if (m_row.m_user.make_row(user))
195     return;
196 
197   m_row.m_event_name.make_row(klass);
198 
199   PFS_connection_stage_visitor visitor(klass);
200   PFS_connection_iterator::visit_user(user,
201                                       true,  /* accounts */
202                                       true,  /* threads */
203                                       false, /* THDs */
204                                       & visitor);
205 
206   if (! user->m_lock.end_optimistic_lock(&lock))
207     return;
208 
209   m_row_exists= true;
210   m_row.m_stat.set(m_normalizer, & visitor.m_stat);
211 }
212 
213 int table_esgs_by_user_by_event_name
read_row_values(TABLE * table,unsigned char * buf,Field ** fields,bool read_all)214 ::read_row_values(TABLE *table, unsigned char *buf, Field **fields,
215                   bool read_all)
216 {
217   Field *f;
218 
219   if (unlikely(! m_row_exists))
220     return HA_ERR_RECORD_DELETED;
221 
222   /* Set the null bits */
223   assert(table->s->null_bytes == 1);
224   buf[0]= 0;
225 
226   for (; (f= *fields) ; fields++)
227   {
228     if (read_all || bitmap_is_set(table->read_set, f->field_index))
229     {
230       switch(f->field_index)
231       {
232       case 0: /* USER */
233         m_row.m_user.set_field(f);
234         break;
235       case 1: /* EVENT_NAME */
236         m_row.m_event_name.set_field(f);
237         break;
238       default: /* 2, ... COUNT/SUM/MIN/AVG/MAX */
239         m_row.m_stat.set_field(f->field_index - 2, f);
240         break;
241       }
242     }
243   }
244 
245   return 0;
246 }
247 
248