aboutsummaryrefslogtreecommitdiff
path: root/mysql/mysql/service_parser.h
blob: 3cf7c8b84c8843013cedfbcd23bbcf76a5a66447 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
#ifndef MYSQL_SERVICE_PARSER_INCLUDED
#define MYSQL_SERVICE_PARSER_INCLUDED
/*  Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.

    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License as
    published by the Free Software Foundation; version 2 of the
    License.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */

#include "my_md5_size.h"
#include <mysql/mysql_lex_string.h>

#ifndef MYSQL_ABI_CHECK
#include <stdlib.h>
#endif

#ifdef __cplusplus
class THD;
class Item;
#define MYSQL_THD THD*
typedef Item* MYSQL_ITEM;
#else
#define MYSQL_THD void*
typedef void* MYSQL_ITEM;
#endif /* __cplusplus */

#ifdef __cplusplus
extern "C" {
#endif

/**
  @file service_parser

  Plugin service that provides access to the parser and some operations on the
  parse tree.
*/

#define PARSER_SERVICE_DIGEST_LENGTH MD5_HASH_SIZE

#define STATEMENT_TYPE_SELECT 1
#define STATEMENT_TYPE_OTHER 2

typedef
int (*parse_node_visit_function)(MYSQL_ITEM item, unsigned char* arg);


typedef
int (*sql_condition_handler_function)(int sql_errno,
                                      const char* sqlstate,
                                      const char* msg,
                                      void *state);

struct st_my_thread_handle;

extern struct mysql_parser_service_st {

  MYSQL_THD (*mysql_current_session)();

  MYSQL_THD (*mysql_open_session)();

  void (*mysql_start_thread)(MYSQL_THD thd, void *(*callback_fun)(void*),
                             void *arg,
                             struct st_my_thread_handle *thread_handle);

  void (*mysql_join_thread)(struct st_my_thread_handle *thread_handle);

  void (*mysql_set_current_database)(MYSQL_THD thd, const MYSQL_LEX_STRING db);

  /**
    Parses the query.

    @param thd The session in which to parse.

    @param query The query to parse.

    @param is_prepared If non-zero, the query will be parsed as a prepared
    statement and won't throw errors when the query string contains '?'.

    @param handle_condition Callback function that is called if a condition is
    raised during the preparation, parsing or cleanup after parsing. If this
    argument is non-NULL, the diagnostics area will be cleared before this
    function returns.

    @param condition_handler_state Will be passed to handle_condition when
    called. Otherwise ignored.

    @retval 0 Success.
    @retval 1 Parse error.
  */
  int (*mysql_parse)(MYSQL_THD thd, const MYSQL_LEX_STRING query,
                     unsigned char is_prepared,
                     sql_condition_handler_function handle_condition,
                     void *condition_handler_state);

  int (*mysql_get_statement_type)(MYSQL_THD thd);

  /**
    Returns the digest of the last parsed statement in the session.

    @param thd The session in which the statement was parsed.

    @param digest[out] An area of at least size PARSER_SERVICE_DIGEST_LENGTH,
    where the digest is written.

    @retval 0 Success.
    @retval 1 Parse error.
  */
  int (*mysql_get_statement_digest)(MYSQL_THD thd, unsigned char *digest);


  /**
    Returns the number of parameters ('?') in the parsed query.
    This works only if the last query was parsed as a prepared statement.

    @param thd The session in which the query was parsed.

    @return The number of parameter markers.
  */
  int (*mysql_get_number_params)(MYSQL_THD thd);


  /**
    Stores in 'positions' the positions in the last parsed query of each
    parameter marker('?'). Positions must be an already allocated array of at
    least mysql_parser_service_st::mysql_get_number_params() size. This works
    only if the last query was parsed as a prepared statement.

    @param thd The session in which the query was parsed.

    @param positions An already allocated array of at least
    mysql_parser_service_st::mysql_get_number_params() size.

    @return The number of parameter markers and hence number of written
    positions.
  */
  int (*mysql_extract_prepared_params)(MYSQL_THD thd, int *positions);


  /**
    Walks the tree depth first and applies a user defined function on each
    literal.

    @param thd The session in which the query was parsed.

    @param processor Will be called for each literal in the parse tree.

    @param arg Will be passed as argument to each call to 'processor'.
  */
  int (*mysql_visit_tree)(MYSQL_THD thd, parse_node_visit_function processor,
                          unsigned char* arg);


  /**
    Renders the MYSQL_ITEM as a string and returns a reference in the form of
    a MYSQL_LEX_STRING. The string buffer is allocated by the server and must
    be freed by mysql_free_string().

    @param item The literal to print.

    @return The result of printing the literal.

    @see mysql_parser_service_st::mysql_free_string().
  */
  MYSQL_LEX_STRING (*mysql_item_string)(MYSQL_ITEM item);


  /**
    Frees a string buffer allocated by the server.

    @param The string whose buffer will be freed.
  */
  void (*mysql_free_string)(MYSQL_LEX_STRING string);


  /**
    Returns the current query string. This string is managed by the server and
    should @b not be freed by a plugin.

    @param thd The session in which the query was submitted.

    @return The query string.
  */
  MYSQL_LEX_STRING (*mysql_get_query)(MYSQL_THD thd);


  /**
    Returns the current query in normalized form. This string is managed by
    the server and should @b not be freed by a plugin.

    @param thd The session in which the query was submitted.

    @return The query string normalized.
  */
  MYSQL_LEX_STRING (*mysql_get_normalized_query)(MYSQL_THD thd);
} *mysql_parser_service;

#ifdef MYSQL_DYNAMIC_PLUGIN

#define mysql_parser_current_session() \
   mysql_parser_service->mysql_current_session()

#define mysql_parser_open_session() \
  mysql_parser_service->mysql_open_session()

#define mysql_parser_start_thread(thd, func, arg, thread_handle) \
  mysql_parser_service->mysql_start_thread(thd, func, arg, thread_handle)

#define mysql_parser_join_thread(thread_handle) \
  mysql_parser_service->mysql_join_thread(thread_handle)

#define mysql_parser_set_current_database(thd, db) \
  mysql_parser_service->mysql_set_current_database(thd, db)

#define mysql_parser_parse(thd, query, is_prepared, \
                           condition_handler, condition_handler_state)  \
  mysql_parser_service->mysql_parse(thd, query, is_prepared, \
                                    condition_handler, \
                                    condition_handler_state)

#define mysql_parser_get_statement_type(thd) \
  mysql_parser_service->mysql_get_statement_type(thd)

#define mysql_parser_get_statement_digest(thd, digest) \
  mysql_parser_service->mysql_get_statement_digest(thd, digest)

#define mysql_parser_get_number_params(thd) \
  mysql_parser_service->mysql_get_number_params(thd)

#define mysql_parser_extract_prepared_params(thd, positions) \
  mysql_parser_service->mysql_extract_prepared_params(thd, positions)

#define mysql_parser_visit_tree(thd, processor, arg) \
  mysql_parser_service->mysql_visit_tree(thd, processor, arg)

#define mysql_parser_item_string(item) \
  mysql_parser_service->mysql_item_string(item)

#define mysql_parser_free_string(string) \
  mysql_parser_service->mysql_free_string(string)

#define mysql_parser_get_query(thd) \
  mysql_parser_service->mysql_get_query(thd)

#define mysql_parser_get_normalized_query(thd) \
  mysql_parser_service->mysql_get_normalized_query(thd)

#else
typedef void *(*callback_function)(void*);
MYSQL_THD mysql_parser_current_session();
MYSQL_THD mysql_parser_open_session();
void mysql_parser_start_thread(MYSQL_THD thd, callback_function fun, void *arg,
                               struct st_my_thread_handle *thread_handle);
void mysql_parser_join_thread(struct st_my_thread_handle *thread_handle);
void mysql_parser_set_current_database(MYSQL_THD thd,
                                       const MYSQL_LEX_STRING db);
int mysql_parser_parse(MYSQL_THD thd, const MYSQL_LEX_STRING query,
                       unsigned char is_prepared,
                       sql_condition_handler_function handle_condition,
                       void *condition_handler_state);
int mysql_parser_get_statement_type(MYSQL_THD thd);
int mysql_parser_get_statement_digest(MYSQL_THD thd, unsigned char *digest);
int mysql_parser_get_number_params(MYSQL_THD thd);
int mysql_parser_extract_prepared_params(MYSQL_THD thd, int *positions);
int mysql_parser_visit_tree(MYSQL_THD thd, parse_node_visit_function processor,
                            unsigned char* arg);
MYSQL_LEX_STRING mysql_parser_item_string(MYSQL_ITEM item);
void mysql_parser_free_string(MYSQL_LEX_STRING string);
MYSQL_LEX_STRING mysql_parser_get_query(MYSQL_THD thd);
MYSQL_LEX_STRING mysql_parser_get_normalized_query(MYSQL_THD thd);

#endif /* MYSQL_DYNAMIC_PLUGIN */

#ifdef __cplusplus
}
#endif

#endif /* MYSQL_SERVICE_PARSER_INCLUDED */