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