1 /* Copyright (c) 2012, 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, Suite 500, Boston, MA 02110-1335 USA */
22
23 /**
24 @file storage/perfschema/table_table_handles.cc
25 Table TABLE_TABLE_HANDLES (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_table_handles.h"
34 #include "pfs_global.h"
35 #include "pfs_stat.h"
36 #include "pfs_buffer_container.h"
37 #include "field.h"
38
39 THR_LOCK table_table_handles::m_table_lock;
40
41 static const TABLE_FIELD_TYPE field_types[]=
42 {
43 {
44 { C_STRING_WITH_LEN("OBJECT_TYPE") },
45 { C_STRING_WITH_LEN("varchar(64)") },
46 { NULL, 0}
47 },
48 {
49 { C_STRING_WITH_LEN("OBJECT_SCHEMA") },
50 { C_STRING_WITH_LEN("varchar(64)") },
51 { NULL, 0}
52 },
53 {
54 { C_STRING_WITH_LEN("OBJECT_NAME") },
55 { C_STRING_WITH_LEN("varchar(64)") },
56 { NULL, 0}
57 },
58 {
59 { C_STRING_WITH_LEN("OBJECT_INSTANCE_BEGIN") },
60 { C_STRING_WITH_LEN("bigint(20)") },
61 { NULL, 0}
62 },
63 {
64 { C_STRING_WITH_LEN("OWNER_THREAD_ID") },
65 { C_STRING_WITH_LEN("bigint(20)") },
66 { NULL, 0}
67 },
68 {
69 { C_STRING_WITH_LEN("OWNER_EVENT_ID") },
70 { C_STRING_WITH_LEN("bigint(20)") },
71 { NULL, 0}
72 },
73 {
74 { C_STRING_WITH_LEN("INTERNAL_LOCK") },
75 { C_STRING_WITH_LEN("varchar(64)") },
76 { NULL, 0}
77 },
78 {
79 { C_STRING_WITH_LEN("EXTERNAL_LOCK") },
80 { C_STRING_WITH_LEN("varchar(64)") },
81 { NULL, 0}
82 }
83 };
84
85 TABLE_FIELD_DEF
86 table_table_handles::m_field_def=
87 { 8, field_types };
88
89 PFS_engine_table_share
90 table_table_handles::m_share=
91 {
92 { C_STRING_WITH_LEN("table_handles") },
93 &pfs_readonly_acl,
94 table_table_handles::create,
95 NULL, /* write_row */
96 NULL, /* delete_all_rows */
97 table_table_handles::get_row_count,
98 sizeof(PFS_simple_index),
99 &m_table_lock,
100 &m_field_def,
101 false, /* checked */
102 false /* perpetual */
103 };
104
105 PFS_engine_table*
create(void)106 table_table_handles::create(void)
107 {
108 return new table_table_handles();
109 }
110
111 ha_rows
get_row_count(void)112 table_table_handles::get_row_count(void)
113 {
114 return global_table_container.get_row_count();
115 }
116
table_table_handles()117 table_table_handles::table_table_handles()
118 : PFS_engine_table(&m_share, &m_pos),
119 m_row_exists(false), m_pos(0), m_next_pos(0)
120 {}
121
reset_position(void)122 void table_table_handles::reset_position(void)
123 {
124 m_pos.m_index= 0;
125 m_next_pos.m_index= 0;
126 }
127
rnd_init(bool scan)128 int table_table_handles::rnd_init(bool scan)
129 {
130 return 0;
131 }
132
rnd_next(void)133 int table_table_handles::rnd_next(void)
134 {
135 PFS_table *pfs;
136
137 m_pos.set_at(&m_next_pos);
138 PFS_table_iterator it= global_table_container.iterate(m_pos.m_index);
139 pfs= it.scan_next(& m_pos.m_index);
140 if (pfs != NULL)
141 {
142 make_row(pfs);
143 m_next_pos.set_after(&m_pos);
144 return 0;
145 }
146
147 return HA_ERR_END_OF_FILE;
148 }
149
150 int
rnd_pos(const void * pos)151 table_table_handles::rnd_pos(const void *pos)
152 {
153 PFS_table *pfs;
154
155 set_position(pos);
156
157 pfs= global_table_container.get(m_pos.m_index);
158 if (pfs != NULL)
159 {
160 make_row(pfs);
161 return 0;
162 }
163
164 return HA_ERR_RECORD_DELETED;
165 }
166
make_row(PFS_table * table)167 void table_table_handles::make_row(PFS_table *table)
168 {
169 pfs_optimistic_state lock;
170 PFS_table_share *share;
171 PFS_thread *thread;
172
173 m_row_exists= false;
174
175 table->m_lock.begin_optimistic_lock(&lock);
176
177 share= sanitize_table_share(table->m_share);
178 if (share == NULL)
179 return;
180
181 if (m_row.m_object.make_row(share))
182 return;
183
184 m_row.m_identity= table->m_identity;
185
186 thread= sanitize_thread(table->m_thread_owner);
187 if (thread != NULL)
188 {
189 m_row.m_owner_thread_id= thread->m_thread_internal_id;
190 m_row.m_owner_event_id= table->m_owner_event_id;
191 }
192 else
193 {
194 m_row.m_owner_thread_id= 0;
195 m_row.m_owner_event_id= 0;
196 }
197
198 m_row.m_internal_lock= table->m_internal_lock;
199 m_row.m_external_lock= table->m_external_lock;
200
201 if (! table->m_lock.end_optimistic_lock(&lock))
202 return;
203
204 m_row_exists= true;
205 }
206
read_row_values(TABLE * table,unsigned char * buf,Field ** fields,bool read_all)207 int table_table_handles::read_row_values(TABLE *table,
208 unsigned char *buf,
209 Field **fields,
210 bool read_all)
211 {
212 Field *f;
213
214 if (unlikely(! m_row_exists))
215 return HA_ERR_RECORD_DELETED;
216
217 /* Set the null bits */
218 assert(table->s->null_bytes == 1);
219 buf[0]= 0;
220
221 for (; (f= *fields) ; fields++)
222 {
223 if (read_all || bitmap_is_set(table->read_set, f->field_index))
224 {
225 switch(f->field_index)
226 {
227 case 0: /* OBJECT_TYPE */
228 case 1: /* SCHEMA_NAME */
229 case 2: /* OBJECT_NAME */
230 m_row.m_object.set_field(f->field_index, f);
231 break;
232 case 3: /* OBJECT_INSTANCE_BEGIN */
233 set_field_ulonglong(f, (intptr) m_row.m_identity);
234 break;
235 case 4: /* OWNER_THREAD_ID */
236 set_field_ulonglong(f, m_row.m_owner_thread_id);
237 break;
238 case 5: /* OWNER_EVENT_ID */
239 set_field_ulonglong(f, m_row.m_owner_event_id);
240 break;
241 case 6: /* INTERNAL_LOCK */
242 set_field_lock_type(f, m_row.m_internal_lock);
243 break;
244 case 7: /* EXTERNAL_LOCK */
245 set_field_lock_type(f, m_row.m_external_lock);
246 break;
247 default:
248 assert(false);
249 }
250 }
251 }
252
253 return 0;
254 }
255
256