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