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