1 /* Copyright (c) 2008, 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 /**
24 @file storage/perfschema/table_file_instances.cc
25 Table FILE_INSTANCES (implementation).
26 */
27
28 #include "my_global.h"
29 #include "my_thread.h"
30 #include "pfs_instr.h"
31 #include "pfs_column_types.h"
32 #include "pfs_column_values.h"
33 #include "table_file_instances.h"
34 #include "pfs_global.h"
35 #include "pfs_buffer_container.h"
36 #include "field.h"
37
38 THR_LOCK table_file_instances::m_table_lock;
39
40 static const TABLE_FIELD_TYPE field_types[]=
41 {
42 {
43 { C_STRING_WITH_LEN("FILE_NAME") },
44 { C_STRING_WITH_LEN("varchar(512)") },
45 { NULL, 0}
46 },
47 {
48 { C_STRING_WITH_LEN("EVENT_NAME") },
49 { C_STRING_WITH_LEN("varchar(128)") },
50 { NULL, 0}
51 },
52 {
53 { C_STRING_WITH_LEN("OPEN_COUNT") },
54 { C_STRING_WITH_LEN("int(10)") },
55 { NULL, 0}
56 }
57 };
58
59 TABLE_FIELD_DEF
60 table_file_instances::m_field_def=
61 { 3, field_types };
62
63 PFS_engine_table_share
64 table_file_instances::m_share=
65 {
66 { C_STRING_WITH_LEN("file_instances") },
67 &pfs_readonly_acl,
68 table_file_instances::create,
69 NULL, /* write_row */
70 NULL, /* delete_all_rows */
71 table_file_instances::get_row_count,
72 sizeof(PFS_simple_index),
73 &m_table_lock,
74 &m_field_def,
75 false, /* checked */
76 false /* perpetual */
77 };
78
create(void)79 PFS_engine_table* table_file_instances::create(void)
80 {
81 return new table_file_instances();
82 }
83
84 ha_rows
get_row_count(void)85 table_file_instances::get_row_count(void)
86 {
87 return global_file_container.get_row_count();
88 }
89
table_file_instances()90 table_file_instances::table_file_instances()
91 : PFS_engine_table(&m_share, &m_pos),
92 m_row_exists(false), m_pos(0), m_next_pos(0)
93 {}
94
reset_position(void)95 void table_file_instances::reset_position(void)
96 {
97 m_pos.m_index= 0;
98 m_next_pos.m_index= 0;
99 }
100
rnd_next(void)101 int table_file_instances::rnd_next(void)
102 {
103 PFS_file *pfs;
104
105 m_pos.set_at(&m_next_pos);
106 PFS_file_iterator it= global_file_container.iterate(m_pos.m_index);
107 pfs= it.scan_next(& m_pos.m_index);
108 if (pfs != NULL)
109 {
110 make_row(pfs);
111 m_next_pos.set_after(&m_pos);
112 return 0;
113 }
114
115 return HA_ERR_END_OF_FILE;
116 }
117
rnd_pos(const void * pos)118 int table_file_instances::rnd_pos(const void *pos)
119 {
120 PFS_file *pfs;
121
122 set_position(pos);
123
124 pfs= global_file_container.get(m_pos.m_index);
125 if (pfs != NULL)
126 {
127 make_row(pfs);
128 return 0;
129 }
130
131 return HA_ERR_RECORD_DELETED;
132 }
133
make_row(PFS_file * pfs)134 void table_file_instances::make_row(PFS_file *pfs)
135 {
136 pfs_optimistic_state lock;
137 PFS_file_class *safe_class;
138
139 m_row_exists= false;
140
141 /* Protect this reader against a file delete */
142 pfs->m_lock.begin_optimistic_lock(&lock);
143
144 safe_class= sanitize_file_class(pfs->m_class);
145 if (unlikely(safe_class == NULL))
146 return;
147
148 m_row.m_filename= pfs->m_filename;
149 m_row.m_filename_length= pfs->m_filename_length;
150 m_row.m_event_name= safe_class->m_name;
151 m_row.m_event_name_length= safe_class->m_name_length;
152 m_row.m_open_count= pfs->m_file_stat.m_open_count;
153
154 if (pfs->m_lock.end_optimistic_lock(&lock))
155 m_row_exists= true;
156 }
157
read_row_values(TABLE * table,unsigned char *,Field ** fields,bool read_all)158 int table_file_instances::read_row_values(TABLE *table,
159 unsigned char *,
160 Field **fields,
161 bool read_all)
162 {
163 Field *f;
164
165 if (unlikely(! m_row_exists))
166 return HA_ERR_RECORD_DELETED;
167
168 /* Set the null bits */
169 assert(table->s->null_bytes == 0);
170
171 for (; (f= *fields) ; fields++)
172 {
173 if (read_all || bitmap_is_set(table->read_set, f->field_index))
174 {
175 switch(f->field_index)
176 {
177 case 0: /* FILENAME */
178 set_field_varchar_utf8(f, m_row.m_filename, m_row.m_filename_length);
179 break;
180 case 1: /* EVENT_NAME */
181 set_field_varchar_utf8(f, m_row.m_event_name,
182 m_row.m_event_name_length);
183 break;
184 case 2: /* OPEN_COUNT */
185 set_field_ulong(f, m_row.m_open_count);
186 break;
187 default:
188 assert(false);
189 }
190 }
191 }
192
193 return 0;
194 }
195
196