1 /* Copyright (c) 2011, 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 Foundation,
21 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
22
23 #include "my_global.h"
24 #include "my_thread.h"
25 #include "table_accounts.h"
26 #include "pfs_instr_class.h"
27 #include "pfs_instr.h"
28 #include "pfs_account.h"
29 #include "pfs_visitor.h"
30 #include "pfs_memory.h"
31 #include "pfs_status.h"
32 #include "field.h"
33
34 THR_LOCK table_accounts::m_table_lock;
35
36 static const TABLE_FIELD_TYPE field_types[]=
37 {
38 {
39 { C_STRING_WITH_LEN("USER") },
40 { C_STRING_WITH_LEN("char(" USERNAME_CHAR_LENGTH_STR ")") },
41 { NULL, 0}
42 },
43 {
44 { C_STRING_WITH_LEN("HOST") },
45 { C_STRING_WITH_LEN("char(60)") },
46 { NULL, 0}
47 },
48 {
49 { C_STRING_WITH_LEN("CURRENT_CONNECTIONS") },
50 { C_STRING_WITH_LEN("bigint(20)") },
51 { NULL, 0}
52 },
53 {
54 { C_STRING_WITH_LEN("TOTAL_CONNECTIONS") },
55 { C_STRING_WITH_LEN("bigint(20)") },
56 { NULL, 0}
57 }
58 };
59
60 TABLE_FIELD_DEF
61 table_accounts::m_field_def=
62 { 4, field_types };
63
64 PFS_engine_table_share
65 table_accounts::m_share=
66 {
67 { C_STRING_WITH_LEN("accounts") },
68 &pfs_truncatable_acl,
69 table_accounts::create,
70 NULL, /* write_row */
71 table_accounts::delete_all_rows,
72 cursor_by_account::get_row_count,
73 sizeof(PFS_simple_index), /* ref length */
74 &m_table_lock,
75 &m_field_def,
76 false, /* checked */
77 false /* perpetual */
78 };
79
create()80 PFS_engine_table* table_accounts::create()
81 {
82 return new table_accounts();
83 }
84
85 int
delete_all_rows(void)86 table_accounts::delete_all_rows(void)
87 {
88 reset_events_waits_by_thread();
89 reset_events_waits_by_account();
90 reset_events_stages_by_thread();
91 reset_events_stages_by_account();
92 reset_events_statements_by_thread();
93 reset_events_statements_by_account();
94 reset_events_transactions_by_thread();
95 reset_events_transactions_by_account();
96 reset_memory_by_thread();
97 reset_memory_by_account();
98 reset_status_by_thread();
99 reset_status_by_account();
100 purge_all_account();
101 return 0;
102 }
103
table_accounts()104 table_accounts::table_accounts()
105 : cursor_by_account(& m_share),
106 m_row_exists(false)
107 {}
108
make_row(PFS_account * pfs)109 void table_accounts::make_row(PFS_account *pfs)
110 {
111 pfs_optimistic_state lock;
112
113 m_row_exists= false;
114 pfs->m_lock.begin_optimistic_lock(&lock);
115
116 if (m_row.m_account.make_row(pfs))
117 return;
118
119 PFS_connection_stat_visitor visitor;
120 PFS_connection_iterator::visit_account(pfs,
121 true, /* threads */
122 false, /* THDs */
123 & visitor);
124
125 if (! pfs->m_lock.end_optimistic_lock(& lock))
126 return;
127
128 m_row.m_connection_stat.set(& visitor.m_stat);
129 m_row_exists= true;
130 }
131
read_row_values(TABLE * table,unsigned char * buf,Field ** fields,bool read_all)132 int table_accounts::read_row_values(TABLE *table,
133 unsigned char *buf,
134 Field **fields,
135 bool read_all)
136 {
137 Field *f;
138
139 if (unlikely(! m_row_exists))
140 return HA_ERR_RECORD_DELETED;
141
142 /* Set the null bits */
143 assert(table->s->null_bytes == 1);
144 buf[0]= 0;
145
146 for (; (f= *fields) ; fields++)
147 {
148 if (read_all || bitmap_is_set(table->read_set, f->field_index))
149 {
150 switch(f->field_index)
151 {
152 case 0: /* USER */
153 case 1: /* HOST */
154 m_row.m_account.set_field(f->field_index, f);
155 break;
156 case 2: /* CURRENT_CONNECTIONS */
157 case 3: /* TOTAL_CONNECTIONS */
158 m_row.m_connection_stat.set_field(f->field_index - 2, f);
159 break;
160 default:
161 assert(false);
162 }
163 }
164 }
165 return 0;
166 }
167
168