1 /* Copyright (c) 2010, 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 St, Fifth Floor, Boston, MA 02110-1301  USA */
22 
23 #ifndef MYSQL_STATEMENT_H
24 #define MYSQL_STATEMENT_H
25 
26 /**
27   @file mysql/psi/mysql_statement.h
28   Instrumentation helpers for statements.
29 */
30 
31 #include "mysql/psi/psi.h"
32 
33 class Diagnostics_area;
34 typedef struct charset_info_st CHARSET_INFO;
35 
36 #ifndef PSI_STATEMENT_CALL
37 #define PSI_STATEMENT_CALL(M) PSI_DYNAMIC_CALL(M)
38 #endif
39 
40 #ifndef PSI_DIGEST_CALL
41 #define PSI_DIGEST_CALL(M) PSI_DYNAMIC_CALL(M)
42 #endif
43 
44 /**
45   @defgroup Statement_instrumentation Statement Instrumentation
46   @ingroup Instrumentation_interface
47   @{
48 */
49 
50 /**
51   @def mysql_statement_register(P1, P2, P3)
52   Statement registration.
53 */
54 #ifdef HAVE_PSI_STATEMENT_INTERFACE
55 #define mysql_statement_register(P1, P2, P3) \
56   inline_mysql_statement_register(P1, P2, P3)
57 #else
58 #define mysql_statement_register(P1, P2, P3) \
59   do {} while (0)
60 #endif
61 
62 #ifdef HAVE_PSI_STATEMENT_DIGEST_INTERFACE
63   #define MYSQL_DIGEST_START(LOCKER) \
64     inline_mysql_digest_start(LOCKER)
65 #else
66   #define MYSQL_DIGEST_START(LOCKER) \
67     NULL
68 #endif
69 
70 #ifdef HAVE_PSI_STATEMENT_DIGEST_INTERFACE
71   #define MYSQL_DIGEST_END(LOCKER, DIGEST) \
72     inline_mysql_digest_end(LOCKER, DIGEST)
73 #else
74   #define MYSQL_DIGEST_END(LOCKER, DIGEST) \
75     do {} while (0)
76 #endif
77 
78 #ifdef HAVE_PSI_STATEMENT_INTERFACE
79   #define MYSQL_START_STATEMENT(STATE, K, DB, DB_LEN, CS, SPS) \
80     inline_mysql_start_statement(STATE, K, DB, DB_LEN, CS, SPS, __FILE__, __LINE__)
81 #else
82   #define MYSQL_START_STATEMENT(STATE, K, DB, DB_LEN, CS, SPS) \
83     NULL
84 #endif
85 
86 #ifdef HAVE_PSI_STATEMENT_INTERFACE
87   #define MYSQL_REFINE_STATEMENT(LOCKER, K) \
88     inline_mysql_refine_statement(LOCKER, K)
89 #else
90   #define MYSQL_REFINE_STATEMENT(LOCKER, K) \
91     NULL
92 #endif
93 
94 #ifdef HAVE_PSI_STATEMENT_INTERFACE
95   #define MYSQL_SET_STATEMENT_TEXT(LOCKER, P1, P2) \
96     inline_mysql_set_statement_text(LOCKER, P1, P2)
97 #else
98   #define MYSQL_SET_STATEMENT_TEXT(LOCKER, P1, P2) \
99     do {} while (0)
100 #endif
101 
102 #ifdef HAVE_PSI_STATEMENT_INTERFACE
103   #define MYSQL_SET_STATEMENT_LOCK_TIME(LOCKER, P1) \
104     inline_mysql_set_statement_lock_time(LOCKER, P1)
105 #else
106   #define MYSQL_SET_STATEMENT_LOCK_TIME(LOCKER, P1) \
107     do {} while (0)
108 #endif
109 
110 #ifdef HAVE_PSI_STATEMENT_INTERFACE
111   #define MYSQL_SET_STATEMENT_ROWS_SENT(LOCKER, P1) \
112     inline_mysql_set_statement_rows_sent(LOCKER, P1)
113 #else
114   #define MYSQL_SET_STATEMENT_ROWS_SENT(LOCKER, P1) \
115     do {} while (0)
116 #endif
117 
118 #ifdef HAVE_PSI_STATEMENT_INTERFACE
119   #define MYSQL_SET_STATEMENT_ROWS_EXAMINED(LOCKER, P1) \
120     inline_mysql_set_statement_rows_examined(LOCKER, P1)
121 #else
122   #define MYSQL_SET_STATEMENT_ROWS_EXAMINED(LOCKER, P1) \
123     do {} while (0)
124 #endif
125 
126 #ifdef HAVE_PSI_STATEMENT_INTERFACE
127   #define MYSQL_END_STATEMENT(LOCKER, DA) \
128     inline_mysql_end_statement(LOCKER, DA)
129 #else
130   #define MYSQL_END_STATEMENT(LOCKER, DA) \
131     do {} while (0)
132 #endif
133 
134 #ifdef HAVE_PSI_STATEMENT_INTERFACE
inline_mysql_statement_register(const char * category,PSI_statement_info * info,int count)135 static inline void inline_mysql_statement_register(
136   const char *category, PSI_statement_info *info, int count)
137 {
138   PSI_STATEMENT_CALL(register_statement)(category, info, count);
139 }
140 
141 #ifdef HAVE_PSI_STATEMENT_DIGEST_INTERFACE
142 static inline struct PSI_digest_locker *
inline_mysql_digest_start(PSI_statement_locker * locker)143 inline_mysql_digest_start(PSI_statement_locker *locker)
144 {
145   PSI_digest_locker* digest_locker= NULL;
146 
147   if (likely(locker != NULL))
148     digest_locker= PSI_DIGEST_CALL(digest_start)(locker);
149   return digest_locker;
150 }
151 #endif
152 
153 #ifdef HAVE_PSI_STATEMENT_DIGEST_INTERFACE
154 static inline void
inline_mysql_digest_end(PSI_digest_locker * locker,const sql_digest_storage * digest)155 inline_mysql_digest_end(PSI_digest_locker *locker, const sql_digest_storage *digest)
156 {
157   if (likely(locker != NULL))
158     PSI_DIGEST_CALL(digest_end)(locker, digest);
159 }
160 #endif
161 
162 static inline struct PSI_statement_locker *
inline_mysql_start_statement(PSI_statement_locker_state * state,PSI_statement_key key,const char * db,uint db_len,const CHARSET_INFO * charset,PSI_sp_share * sp_share,const char * src_file,int src_line)163 inline_mysql_start_statement(PSI_statement_locker_state *state,
164                              PSI_statement_key key,
165                              const char *db, uint db_len,
166                              const CHARSET_INFO *charset,
167                              PSI_sp_share *sp_share,
168                              const char *src_file, int src_line)
169 {
170   PSI_statement_locker *locker;
171   locker= PSI_STATEMENT_CALL(get_thread_statement_locker)(state, key, charset,
172                                                           sp_share);
173   if (likely(locker != NULL))
174     PSI_STATEMENT_CALL(start_statement)(locker, db, db_len, src_file, src_line);
175   return locker;
176 }
177 
178 static inline struct PSI_statement_locker *
inline_mysql_refine_statement(PSI_statement_locker * locker,PSI_statement_key key)179 inline_mysql_refine_statement(PSI_statement_locker *locker,
180                               PSI_statement_key key)
181 {
182   if (likely(locker != NULL))
183   {
184     locker= PSI_STATEMENT_CALL(refine_statement)(locker, key);
185   }
186   return locker;
187 }
188 
189 static inline void
inline_mysql_set_statement_text(PSI_statement_locker * locker,const char * text,uint text_len)190 inline_mysql_set_statement_text(PSI_statement_locker *locker,
191                                 const char *text, uint text_len)
192 {
193   if (likely(locker != NULL))
194   {
195     PSI_STATEMENT_CALL(set_statement_text)(locker, text, text_len);
196   }
197 }
198 
199 static inline void
inline_mysql_set_statement_lock_time(PSI_statement_locker * locker,ulonglong count)200 inline_mysql_set_statement_lock_time(PSI_statement_locker *locker,
201                                      ulonglong count)
202 {
203   if (likely(locker != NULL))
204   {
205     PSI_STATEMENT_CALL(set_statement_lock_time)(locker, count);
206   }
207 }
208 
209 static inline void
inline_mysql_set_statement_rows_sent(PSI_statement_locker * locker,ulonglong count)210 inline_mysql_set_statement_rows_sent(PSI_statement_locker *locker,
211                                      ulonglong count)
212 {
213   if (likely(locker != NULL))
214   {
215     PSI_STATEMENT_CALL(set_statement_rows_sent)(locker, count);
216   }
217 }
218 
219 static inline void
inline_mysql_set_statement_rows_examined(PSI_statement_locker * locker,ulonglong count)220 inline_mysql_set_statement_rows_examined(PSI_statement_locker *locker,
221                                          ulonglong count)
222 {
223   if (likely(locker != NULL))
224   {
225     PSI_STATEMENT_CALL(set_statement_rows_examined)(locker, count);
226   }
227 }
228 
229 static inline void
inline_mysql_end_statement(struct PSI_statement_locker * locker,Diagnostics_area * stmt_da)230 inline_mysql_end_statement(struct PSI_statement_locker *locker,
231                            Diagnostics_area *stmt_da)
232 {
233   PSI_STAGE_CALL(end_stage)();
234   if (likely(locker != NULL))
235     PSI_STATEMENT_CALL(end_statement)(locker, stmt_da);
236 }
237 #endif
238 
239 /** @} (end of group Statement_instrumentation) */
240 
241 #endif
242 
243