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