1 /* Copyright (c) 2010, 2021, Oracle and/or its affiliates.
2    Copyright (c) 2017, 2019, MariaDB Corporation.
3 
4   This program is free software; you can redistribute it and/or modify
5   it under the terms of the GNU General Public License, version 2.0,
6   as published by the Free Software Foundation.
7 
8   This program is also distributed with certain software (including
9   but not limited to OpenSSL) that is licensed under separate terms,
10   as designated in a particular file or component or in included license
11   documentation.  The authors of MySQL hereby grant you an additional
12   permission to link the program and your derivative works with the
13   separately licensed software that they have included with MySQL.
14 
15   This program is distributed in the hope that it will be useful,
16   but WITHOUT ANY WARRANTY; without even the implied warranty of
17   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18   GNU General Public License, version 2.0, for more details.
19 
20   You should have received a copy of the GNU General Public License
21   along with this program; if not, write to the Free Software
22   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335  USA */
23 
24 #ifndef MYSQL_STATEMENT_H
25 #define MYSQL_STATEMENT_H
26 
27 /**
28   @file mysql/psi/mysql_statement.h
29   Instrumentation helpers for statements.
30 */
31 
32 #include "mysql/psi/psi.h"
33 
34 class Diagnostics_area;
35 typedef const struct charset_info_st CHARSET_INFO;
36 
37 #ifndef PSI_STATEMENT_CALL
38 #define PSI_STATEMENT_CALL(M) PSI_DYNAMIC_CALL(M)
39 #endif
40 
41 #ifndef PSI_DIGEST_CALL
42 #define PSI_DIGEST_CALL(M) PSI_DYNAMIC_CALL(M)
43 #endif
44 
45 /**
46   @defgroup Statement_instrumentation Statement Instrumentation
47   @ingroup Instrumentation_interface
48   @{
49 */
50 
51 /**
52   @def mysql_statement_register(P1, P2, P3)
53   Statement registration.
54 */
55 #ifdef HAVE_PSI_STATEMENT_INTERFACE
56 #define mysql_statement_register(P1, P2, P3) \
57   inline_mysql_statement_register(P1, P2, P3)
58 #else
59 #define mysql_statement_register(P1, P2, P3) \
60   do {} while (0)
61 #endif
62 
63 #ifdef HAVE_PSI_STATEMENT_DIGEST_INTERFACE
64   #define MYSQL_DIGEST_START(LOCKER) \
65     inline_mysql_digest_start(LOCKER)
66 #else
67   #define MYSQL_DIGEST_START(LOCKER) \
68     NULL
69 #endif
70 
71 #ifdef HAVE_PSI_STATEMENT_DIGEST_INTERFACE
72   #define MYSQL_DIGEST_END(LOCKER, DIGEST) \
73     inline_mysql_digest_end(LOCKER, DIGEST)
74 #else
75   #define MYSQL_DIGEST_END(LOCKER, DIGEST) \
76     do {} while (0)
77 #endif
78 
79 #ifdef HAVE_PSI_STATEMENT_INTERFACE
80   #define MYSQL_START_STATEMENT(STATE, K, DB, DB_LEN, CS, SPS) \
81     inline_mysql_start_statement(STATE, K, DB, DB_LEN, CS, SPS, __FILE__, __LINE__)
82 #else
83   #define MYSQL_START_STATEMENT(STATE, K, DB, DB_LEN, CS, SPS) \
84     NULL
85 #endif
86 
87 #ifdef HAVE_PSI_STATEMENT_INTERFACE
88   #define MYSQL_REFINE_STATEMENT(LOCKER, K) \
89     inline_mysql_refine_statement(LOCKER, K)
90 #else
91   #define MYSQL_REFINE_STATEMENT(LOCKER, K) \
92     NULL
93 #endif
94 
95 #ifdef HAVE_PSI_STATEMENT_INTERFACE
96   #define MYSQL_SET_STATEMENT_TEXT(LOCKER, P1, P2) \
97     inline_mysql_set_statement_text(LOCKER, P1, P2)
98 #else
99   #define MYSQL_SET_STATEMENT_TEXT(LOCKER, P1, P2) \
100     do {} while (0)
101 #endif
102 
103 #ifdef HAVE_PSI_STATEMENT_INTERFACE
104   #define MYSQL_SET_STATEMENT_LOCK_TIME(LOCKER, P1) \
105     inline_mysql_set_statement_lock_time(LOCKER, P1)
106 #else
107   #define MYSQL_SET_STATEMENT_LOCK_TIME(LOCKER, P1) \
108     do {} while (0)
109 #endif
110 
111 #ifdef HAVE_PSI_STATEMENT_INTERFACE
112   #define MYSQL_SET_STATEMENT_ROWS_SENT(LOCKER, P1) \
113     inline_mysql_set_statement_rows_sent(LOCKER, P1)
114 #else
115   #define MYSQL_SET_STATEMENT_ROWS_SENT(LOCKER, P1) \
116     do {} while (0)
117 #endif
118 
119 #ifdef HAVE_PSI_STATEMENT_INTERFACE
120   #define MYSQL_SET_STATEMENT_ROWS_EXAMINED(LOCKER, P1) \
121     inline_mysql_set_statement_rows_examined(LOCKER, P1)
122 #else
123   #define MYSQL_SET_STATEMENT_ROWS_EXAMINED(LOCKER, P1) \
124     do {} while (0)
125 #endif
126 
127 #ifdef HAVE_PSI_STATEMENT_INTERFACE
128   #define MYSQL_END_STATEMENT(LOCKER, DA) \
129     inline_mysql_end_statement(LOCKER, DA)
130 #else
131   #define MYSQL_END_STATEMENT(LOCKER, DA) \
132     do {} while (0)
133 #endif
134 
135 #ifdef HAVE_PSI_STATEMENT_INTERFACE
inline_mysql_statement_register(const char * category,PSI_statement_info * info,int count)136 static inline void inline_mysql_statement_register(
137   const char *category, PSI_statement_info *info, int count)
138 {
139   PSI_STATEMENT_CALL(register_statement)(category, info, count);
140 }
141 
142 #ifdef HAVE_PSI_STATEMENT_DIGEST_INTERFACE
143 static inline struct PSI_digest_locker *
inline_mysql_digest_start(PSI_statement_locker * locker)144 inline_mysql_digest_start(PSI_statement_locker *locker)
145 {
146   PSI_digest_locker* digest_locker= NULL;
147 
148   if (psi_likely(locker != NULL))
149     digest_locker= PSI_DIGEST_CALL(digest_start)(locker);
150   return digest_locker;
151 }
152 #endif
153 
154 #ifdef HAVE_PSI_STATEMENT_DIGEST_INTERFACE
155 static inline void
inline_mysql_digest_end(PSI_digest_locker * locker,const sql_digest_storage * digest)156 inline_mysql_digest_end(PSI_digest_locker *locker, const sql_digest_storage *digest)
157 {
158   if (psi_likely(locker != NULL))
159     PSI_DIGEST_CALL(digest_end)(locker, digest);
160 }
161 #endif
162 
163 static inline struct PSI_statement_locker *
inline_mysql_start_statement(PSI_statement_locker_state * state,PSI_statement_key key,const char * db,size_t db_len,CHARSET_INFO * charset,PSI_sp_share * sp_share,const char * src_file,uint src_line)164 inline_mysql_start_statement(PSI_statement_locker_state *state,
165                              PSI_statement_key key,
166                              const char *db, size_t db_len,
167                              CHARSET_INFO *charset,
168                              PSI_sp_share *sp_share,
169                              const char *src_file, uint src_line)
170 {
171   PSI_statement_locker *locker;
172   locker= PSI_STATEMENT_CALL(get_thread_statement_locker)(state, key, charset,
173                                                           sp_share);
174   if (psi_likely(locker != NULL))
175     PSI_STATEMENT_CALL(start_statement)(locker, db, (uint)db_len, src_file, src_line);
176   return locker;
177 }
178 
179 static inline struct PSI_statement_locker *
inline_mysql_refine_statement(PSI_statement_locker * locker,PSI_statement_key key)180 inline_mysql_refine_statement(PSI_statement_locker *locker,
181                               PSI_statement_key key)
182 {
183   if (psi_likely(locker != NULL))
184   {
185     locker= PSI_STATEMENT_CALL(refine_statement)(locker, key);
186   }
187   return locker;
188 }
189 
190 static inline void
inline_mysql_set_statement_text(PSI_statement_locker * locker,const char * text,uint text_len)191 inline_mysql_set_statement_text(PSI_statement_locker *locker,
192                                 const char *text, uint text_len)
193 {
194   if (psi_likely(locker != NULL))
195   {
196     PSI_STATEMENT_CALL(set_statement_text)(locker, text, text_len);
197   }
198 }
199 
200 static inline void
inline_mysql_set_statement_lock_time(PSI_statement_locker * locker,ulonglong count)201 inline_mysql_set_statement_lock_time(PSI_statement_locker *locker,
202                                      ulonglong count)
203 {
204   if (psi_likely(locker != NULL))
205   {
206     PSI_STATEMENT_CALL(set_statement_lock_time)(locker, count);
207   }
208 }
209 
210 static inline void
inline_mysql_set_statement_rows_sent(PSI_statement_locker * locker,ulonglong count)211 inline_mysql_set_statement_rows_sent(PSI_statement_locker *locker,
212                                      ulonglong count)
213 {
214   if (psi_likely(locker != NULL))
215   {
216     PSI_STATEMENT_CALL(set_statement_rows_sent)(locker, count);
217   }
218 }
219 
220 static inline void
inline_mysql_set_statement_rows_examined(PSI_statement_locker * locker,ulonglong count)221 inline_mysql_set_statement_rows_examined(PSI_statement_locker *locker,
222                                          ulonglong count)
223 {
224   if (psi_likely(locker != NULL))
225   {
226     PSI_STATEMENT_CALL(set_statement_rows_examined)(locker, count);
227   }
228 }
229 
230 static inline void
inline_mysql_end_statement(struct PSI_statement_locker * locker,Diagnostics_area * stmt_da)231 inline_mysql_end_statement(struct PSI_statement_locker *locker,
232                            Diagnostics_area *stmt_da)
233 {
234   PSI_STAGE_CALL(end_stage)();
235   if (psi_likely(locker != NULL))
236     PSI_STATEMENT_CALL(end_statement)(locker, stmt_da);
237 }
238 #endif
239 
240 /** @} (end of group Statement_instrumentation) */
241 
242 #endif
243 
244