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, Suite 500, Boston, MA 02110-1335 USA */
22 
23 /**
24   @file storage/perfschema/table_ets_by_user_by_event_name.cc
25   Table EVENTS_TRANSACTIONS_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_ets_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_ets_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("COUNT_READ_WRITE") },
80     { C_STRING_WITH_LEN("bigint(20)") },
81     { NULL, 0}
82   },
83   {
84     { C_STRING_WITH_LEN("SUM_TIMER_READ_WRITE") },
85     { C_STRING_WITH_LEN("bigint(20)") },
86     { NULL, 0}
87   },
88   {
89     { C_STRING_WITH_LEN("MIN_TIMER_READ_WRITE") },
90     { C_STRING_WITH_LEN("bigint(20)") },
91     { NULL, 0}
92   },
93   {
94     { C_STRING_WITH_LEN("AVG_TIMER_READ_WRITE") },
95     { C_STRING_WITH_LEN("bigint(20)") },
96     { NULL, 0}
97   },
98   {
99     { C_STRING_WITH_LEN("MAX_TIMER_READ_WRITE") },
100     { C_STRING_WITH_LEN("bigint(20)") },
101     { NULL, 0}
102   },
103   {
104     { C_STRING_WITH_LEN("COUNT_READ_ONLY") },
105     { C_STRING_WITH_LEN("bigint(20)") },
106     { NULL, 0}
107   },
108   {
109     { C_STRING_WITH_LEN("SUM_TIMER_READ_ONLY") },
110     { C_STRING_WITH_LEN("bigint(20)") },
111     { NULL, 0}
112   },
113   {
114     { C_STRING_WITH_LEN("MIN_TIMER_READ_ONLY") },
115     { C_STRING_WITH_LEN("bigint(20)") },
116     { NULL, 0}
117   },
118   {
119     { C_STRING_WITH_LEN("AVG_TIMER_READ_ONLY") },
120     { C_STRING_WITH_LEN("bigint(20)") },
121     { NULL, 0}
122   },
123   {
124     { C_STRING_WITH_LEN("MAX_TIMER_READ_ONLY") },
125     { C_STRING_WITH_LEN("bigint(20)") },
126     { NULL, 0}
127   }
128 };
129 
130 TABLE_FIELD_DEF
131 table_ets_by_user_by_event_name::m_field_def=
132 { 17, field_types };
133 
134 PFS_engine_table_share
135 table_ets_by_user_by_event_name::m_share=
136 {
137   { C_STRING_WITH_LEN("events_transactions_summary_by_user_by_event_name") },
138   &pfs_truncatable_acl,
139   table_ets_by_user_by_event_name::create,
140   NULL, /* write_row */
141   table_ets_by_user_by_event_name::delete_all_rows,
142   table_ets_by_user_by_event_name::get_row_count,
143   sizeof(pos_ets_by_user_by_event_name),
144   &m_table_lock,
145   &m_field_def,
146   false, /* checked */
147   false  /* perpetual */
148 };
149 
150 PFS_engine_table*
create(void)151 table_ets_by_user_by_event_name::create(void)
152 {
153   return new table_ets_by_user_by_event_name();
154 }
155 
156 int
delete_all_rows(void)157 table_ets_by_user_by_event_name::delete_all_rows(void)
158 {
159   reset_events_transactions_by_thread();
160   reset_events_transactions_by_account();
161   reset_events_transactions_by_user();
162   return 0;
163 }
164 
165 ha_rows
get_row_count(void)166 table_ets_by_user_by_event_name::get_row_count(void)
167 {
168   return global_user_container.get_row_count() * transaction_class_max;
169 }
170 
table_ets_by_user_by_event_name()171 table_ets_by_user_by_event_name::table_ets_by_user_by_event_name()
172   : PFS_engine_table(&m_share, &m_pos),
173     m_row_exists(false), m_pos(), m_next_pos()
174 {}
175 
reset_position(void)176 void table_ets_by_user_by_event_name::reset_position(void)
177 {
178   m_pos.reset();
179   m_next_pos.reset();
180 }
181 
rnd_init(bool scan)182 int table_ets_by_user_by_event_name::rnd_init(bool scan)
183 {
184   m_normalizer= time_normalizer::get(transaction_timer);
185   return 0;
186 }
187 
rnd_next(void)188 int table_ets_by_user_by_event_name::rnd_next(void)
189 {
190   PFS_user *user;
191   PFS_transaction_class *transaction_class;
192   bool has_more_user= true;
193 
194   for (m_pos.set_at(&m_next_pos);
195        has_more_user;
196        m_pos.next_user())
197   {
198     user= global_user_container.get(m_pos.m_index_1, & has_more_user);
199     if (user != NULL)
200     {
201       transaction_class= find_transaction_class(m_pos.m_index_2);
202       if (transaction_class)
203       {
204         make_row(user, transaction_class);
205         m_next_pos.set_after(&m_pos);
206         return 0;
207       }
208     }
209   }
210 
211   return HA_ERR_END_OF_FILE;
212 }
213 
214 int
rnd_pos(const void * pos)215 table_ets_by_user_by_event_name::rnd_pos(const void *pos)
216 {
217   PFS_user *user;
218   PFS_transaction_class *transaction_class;
219 
220   set_position(pos);
221 
222   user= global_user_container.get(m_pos.m_index_1);
223   if (user != NULL)
224   {
225     transaction_class= find_transaction_class(m_pos.m_index_2);
226     if (transaction_class)
227     {
228       make_row(user, transaction_class);
229       return 0;
230     }
231   }
232 
233   return HA_ERR_RECORD_DELETED;
234 }
235 
236 void table_ets_by_user_by_event_name
make_row(PFS_user * user,PFS_transaction_class * klass)237 ::make_row(PFS_user *user, PFS_transaction_class *klass)
238 {
239   pfs_optimistic_state lock;
240   m_row_exists= false;
241 
242   user->m_lock.begin_optimistic_lock(&lock);
243 
244   if (m_row.m_user.make_row(user))
245     return;
246 
247   m_row.m_event_name.make_row(klass);
248 
249   PFS_connection_transaction_visitor visitor(klass);
250   PFS_connection_iterator::visit_user(user,
251                                       true,  /* accounts */
252                                       true,  /* threads */
253                                       false, /* THDs */
254                                       & visitor);
255 
256   if (! user->m_lock.end_optimistic_lock(&lock))
257     return;
258 
259   m_row_exists= true;
260   m_row.m_stat.set(m_normalizer, & visitor.m_stat);
261 }
262 
263 int table_ets_by_user_by_event_name
read_row_values(TABLE * table,unsigned char * buf,Field ** fields,bool read_all)264 ::read_row_values(TABLE *table, unsigned char *buf, Field **fields,
265                   bool read_all)
266 {
267   Field *f;
268 
269   if (unlikely(! m_row_exists))
270     return HA_ERR_RECORD_DELETED;
271 
272   /* Set the null bits */
273   assert(table->s->null_bytes == 1);
274   buf[0]= 0;
275 
276   for (; (f= *fields) ; fields++)
277   {
278     if (read_all || bitmap_is_set(table->read_set, f->field_index))
279     {
280       switch(f->field_index)
281       {
282       case 0: /* USER */
283         m_row.m_user.set_field(f);
284         break;
285       case 1: /* EVENT_NAME */
286         m_row.m_event_name.set_field(f);
287         break;
288       default:
289         /**
290           COUNT_STAR, SUM/MIN/AVG/MAX_TIMER_WAIT,
291           COUNT_READ_WRITE, SUM/MIN/AVG/MAX_TIMER_READ_WRITE,
292           COUNT_READ_ONLY, SUM/MIN/AVG/MAX_TIMER_READ_ONLY
293          */
294         m_row.m_stat.set_field(f->field_index-2, f);
295         break;
296       }
297     }
298   }
299 
300   return 0;
301 }
302 
303