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