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_setup_timers.cc
25   Table SETUP_TIMERS (implementation).
26 */
27 
28 #include "my_global.h"
29 #include "my_thread.h"
30 #include "table_setup_timers.h"
31 #include "pfs_column_values.h"
32 #include "pfs_timer.h"
33 #include "field.h"
34 #include "derror.h" /* ER_THD */
35 
36 #define COUNT_SETUP_TIMERS 5
37 
38 static row_setup_timers all_setup_timers_data[COUNT_SETUP_TIMERS]=
39 {
40   {
41     { C_STRING_WITH_LEN("idle") },
42     &idle_timer
43   },
44   {
45     { C_STRING_WITH_LEN("wait") },
46     &wait_timer
47   },
48   {
49     { C_STRING_WITH_LEN("stage") },
50     &stage_timer
51   },
52   {
53     { C_STRING_WITH_LEN("statement") },
54     &statement_timer
55   },
56   {
57     { C_STRING_WITH_LEN("transaction") },
58     &transaction_timer
59   }
60 };
61 
62 THR_LOCK table_setup_timers::m_table_lock;
63 
64 static const TABLE_FIELD_TYPE field_types[]=
65 {
66   {
67     { C_STRING_WITH_LEN("NAME") },
68     { C_STRING_WITH_LEN("varchar(64)") },
69     { NULL, 0}
70   },
71   {
72     { C_STRING_WITH_LEN("TIMER_NAME") },
73     { C_STRING_WITH_LEN("enum(\'CYCLE\',\'NANOSECOND\',\'MICROSECOND\',"
74                         "\'MILLISECOND\',\'TICK\')") },
75     { NULL, 0}
76   }
77 };
78 
79 TABLE_FIELD_DEF
80 table_setup_timers::m_field_def=
81 { 2, field_types };
82 
83 PFS_engine_table_share
84 table_setup_timers::m_share=
85 {
86   { C_STRING_WITH_LEN("setup_timers") },
87   &pfs_updatable_acl,
88   table_setup_timers::create,
89   NULL, /* write_row */
90   NULL, /* delete_all_rows */
91   table_setup_timers::get_row_count,
92   sizeof(PFS_simple_index),
93   &m_table_lock,
94   &m_field_def,
95   false, /* checked */
96   false  /* perpetual */
97 };
98 
create(void)99 PFS_engine_table* table_setup_timers::create(void)
100 {
101   THD *thd = current_thd;
102   push_warning_printf(thd,
103                       Sql_condition::SL_WARNING,
104                       ER_WARN_DEPRECATED_SYNTAX_NO_REPLACEMENT,
105                       ER_THD(thd, ER_WARN_DEPRECATED_SYNTAX_NO_REPLACEMENT),
106                       "performance_schema.setup_timers");
107 
108   return new table_setup_timers();
109 }
110 
111 ha_rows
get_row_count(void)112 table_setup_timers::get_row_count(void)
113 {
114   return COUNT_SETUP_TIMERS;
115 }
116 
table_setup_timers()117 table_setup_timers::table_setup_timers()
118   : PFS_engine_table(&m_share, &m_pos),
119     m_row(NULL), m_pos(0), m_next_pos(0)
120 {}
121 
reset_position(void)122 void table_setup_timers::reset_position(void)
123 {
124   m_pos.m_index= 0;
125   m_next_pos.m_index= 0;
126 }
127 
rnd_next(void)128 int table_setup_timers::rnd_next(void)
129 {
130   int result;
131 
132   m_pos.set_at(&m_next_pos);
133 
134   if (m_pos.m_index < COUNT_SETUP_TIMERS)
135   {
136     m_row= &all_setup_timers_data[m_pos.m_index];
137     m_next_pos.set_after(&m_pos);
138     result= 0;
139   }
140   else
141   {
142     m_row= NULL;
143     result= HA_ERR_END_OF_FILE;
144   }
145 
146   return result;
147 }
148 
rnd_pos(const void * pos)149 int table_setup_timers::rnd_pos(const void *pos)
150 {
151   set_position(pos);
152   assert(m_pos.m_index < COUNT_SETUP_TIMERS);
153   m_row= &all_setup_timers_data[m_pos.m_index];
154   return 0;
155 }
156 
read_row_values(TABLE * table,unsigned char *,Field ** fields,bool read_all)157 int table_setup_timers::read_row_values(TABLE *table,
158                                         unsigned char *,
159                                         Field **fields,
160                                         bool read_all)
161 {
162   Field *f;
163 
164   assert(m_row);
165 
166   /* Set the null bits */
167   assert(table->s->null_bytes == 0);
168 
169   for (; (f= *fields) ; fields++)
170   {
171     if (read_all || bitmap_is_set(table->read_set, f->field_index))
172     {
173       switch(f->field_index)
174       {
175       case 0: /* NAME */
176         set_field_varchar_utf8(f, m_row->m_name.str, m_row->m_name.length);
177         break;
178       case 1: /* TIMER_NAME */
179         set_field_enum(f, *(m_row->m_timer_name_ptr));
180         break;
181       default:
182         assert(false);
183       }
184     }
185   }
186 
187   return 0;
188 }
189 
update_row_values(TABLE * table,const unsigned char *,unsigned char *,Field ** fields)190 int table_setup_timers::update_row_values(TABLE *table,
191                                           const unsigned char *,
192                                           unsigned char *,
193                                           Field **fields)
194 {
195   Field *f;
196   longlong value;
197 
198   assert(m_row);
199 
200   for (; (f= *fields) ; fields++)
201   {
202     if (bitmap_is_set(table->write_set, f->field_index))
203     {
204       switch(f->field_index)
205       {
206       case 0: /* NAME */
207         return HA_ERR_WRONG_COMMAND;
208       case 1: /* TIMER_NAME */
209         value= get_field_enum(f);
210         if ((value >= FIRST_TIMER_NAME) && (value <= LAST_TIMER_NAME))
211           *(m_row->m_timer_name_ptr)= (enum_timer_name) value;
212         else
213           return HA_ERR_WRONG_COMMAND;
214         break;
215       default:
216         assert(false);
217       }
218     }
219   }
220 
221   return 0;
222 }
223 
224