1#ifndef SQL_PREPARE_H
2#define SQL_PREPARE_H
3/* Copyright (c) 1995-2008 MySQL AB, 2009 Sun Microsystems, Inc.
4 Use is subject to license terms.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; version 2 of the License.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
18
19#include "sql_error.h"
20
21
22#define LAST_STMT_ID 0xFFFFFFFF
23#define STMT_ID_MASK 0x7FFFFFFF
24
25class THD;
26struct LEX;
27
28/**
29 An interface that is used to take an action when
30 the locking module notices that a table version has changed
31 since the last execution. "Table" here may refer to any kind of
32 table -- a base table, a temporary table, a view or an
33 information schema table.
34
35 When we open and lock tables for execution of a prepared
36 statement, we must verify that they did not change
37 since statement prepare. If some table did change, the statement
38 parse tree *may* be no longer valid, e.g. in case it contains
39 optimizations that depend on table metadata.
40
41 This class provides an interface (a method) that is
42 invoked when such a situation takes place.
43 The implementation of the method simply reports an error, but
44 the exact details depend on the nature of the SQL statement.
45
46 At most 1 instance of this class is active at a time, in which
47 case THD::m_reprepare_observer is not NULL.
48
49 @sa check_and_update_table_version() for details of the
50 version tracking algorithm
51
52 @sa Open_tables_state::m_reprepare_observer for the life cycle
53 of metadata observers.
54*/
55
56class Reprepare_observer
57{
58public:
59 /**
60 Check if a change of metadata is OK. In future
61 the signature of this method may be extended to accept the old
62 and the new versions, but since currently the check is very
63 simple, we only need the THD to report an error.
64 */
65 bool report_error(THD *thd);
66 bool is_invalidated() const { return m_invalidated; }
67 void reset_reprepare_observer() { m_invalidated= FALSE; }
68private:
69 bool m_invalidated;
70};
71
72
73void mysqld_stmt_prepare(THD *thd, const char *packet, uint packet_length);
74void mysqld_stmt_execute(THD *thd, char *packet, uint packet_length);
75void mysqld_stmt_execute_bulk(THD *thd, char *packet, uint packet_length);
76void mysqld_stmt_bulk_execute(THD *thd, char *packet, uint packet_length);
77void mysqld_stmt_close(THD *thd, char *packet);
78void mysql_sql_stmt_prepare(THD *thd);
79void mysql_sql_stmt_execute(THD *thd);
80void mysql_sql_stmt_execute_immediate(THD *thd);
81void mysql_sql_stmt_close(THD *thd);
82void mysqld_stmt_fetch(THD *thd, char *packet, uint packet_length);
83void mysqld_stmt_reset(THD *thd, char *packet);
84void mysql_stmt_get_longdata(THD *thd, char *pos, ulong packet_length);
85void reinit_stmt_before_use(THD *thd, LEX *lex);
86
87my_bool bulk_parameters_iterations(THD *thd);
88my_bool bulk_parameters_set(THD *thd);
89/**
90 Execute a fragment of server code in an isolated context, so that
91 it doesn't leave any effect on THD. THD must have no open tables.
92 The code must not leave any open tables around.
93 The result of execution (if any) is stored in Ed_result.
94*/
95
96class Server_runnable
97{
98public:
99 virtual bool execute_server_code(THD *thd)= 0;
100 virtual ~Server_runnable();
101};
102
103
104/**
105 Execute direct interface.
106
107 @todo Implement support for prelocked mode.
108*/
109
110class Ed_row;
111
112/**
113 Ed_result_set -- a container with result set rows.
114 @todo Implement support for result set metadata and
115 automatic type conversion.
116*/
117
118class Ed_result_set: public Sql_alloc
119{
120public:
121 operator List<Ed_row>&() { return *m_rows; }
122 unsigned int size() const { return m_rows->elements; }
123
124 Ed_result_set(List<Ed_row> *rows_arg, size_t column_count,
125 MEM_ROOT *mem_root_arg);
126
127 /** We don't call member destructors, they all are POD types. */
128 ~Ed_result_set() {}
129
130 size_t get_field_count() const { return m_column_count; }
131
132 static void operator delete(void *ptr, size_t size) throw ();
133 static void operator delete(void *, MEM_ROOT *){}
134private:
135 Ed_result_set(const Ed_result_set &); /* not implemented */
136 Ed_result_set &operator=(Ed_result_set &); /* not implemented */
137private:
138 MEM_ROOT m_mem_root;
139 size_t m_column_count;
140 List<Ed_row> *m_rows;
141 Ed_result_set *m_next_rset;
142 friend class Ed_connection;
143};
144
145
146class Ed_connection
147{
148public:
149 /**
150 Construct a new "execute direct" connection.
151
152 The connection can be used to execute SQL statements.
153 If the connection failed to initialize, the error
154 will be returned on the attempt to execute a statement.
155
156 @pre thd must have no open tables
157 while the connection is used. However,
158 Ed_connection works okay in LOCK TABLES mode.
159 Other properties of THD, such as the current warning
160 information, errors, etc. do not matter and are
161 preserved by Ed_connection. One thread may have many
162 Ed_connections created for it.
163 */
164 Ed_connection(THD *thd);
165
166 /**
167 Execute one SQL statement.
168
169 Until this method is executed, no other methods of
170 Ed_connection can be used. Life cycle of Ed_connection is:
171
172 Initialized -> a statement has been executed ->
173 look at result, move to next result ->
174 look at result, move to next result ->
175 ...
176 moved beyond the last result == Initialized.
177
178 This method can be called repeatedly. Once it's invoked,
179 results of the previous execution are lost.
180
181 A result of execute_direct() can be either:
182
183 - success, no result set rows. In this case get_field_count()
184 returns 0. This happens after execution of INSERT, UPDATE,
185 DELETE, DROP and similar statements. Some other methods, such
186 as get_affected_rows() can be used to retrieve additional
187 result information.
188
189 - success, there are some result set rows (maybe 0). E.g.
190 happens after SELECT. In this case get_field_count() returns
191 the number of columns in a result set and store_result()
192 can be used to retrieve a result set..
193
194 - an error, methods to retrieve error information can
195 be used.
196
197 @return execution status
198 @retval FALSE success, use get_field_count()
199 to determine what to do next.
200 @retval TRUE error, use get_last_error()
201 to see the error number.
202 */
203 bool execute_direct(LEX_STRING sql_text);
204
205 /**
206 Same as the previous, but takes an instance of Server_runnable
207 instead of SQL statement text.
208
209 @return execution status
210
211 @retval FALSE success, use get_field_count()
212 if your code fragment is supposed to
213 return a result set
214 @retval TRUE failure
215 */
216 bool execute_direct(Server_runnable *server_runnable);
217
218 /**
219 Get the number of affected (deleted, updated)
220 rows for the current statement. Can be
221 used for statements with get_field_count() == 0.
222
223 @sa Documentation for C API function
224 mysql_affected_rows().
225 */
226 ulonglong get_affected_rows() const
227 {
228 return m_diagnostics_area.affected_rows();
229 }
230
231 /**
232 Get the last insert id, if any.
233
234 @sa Documentation for mysql_insert_id().
235 */
236 ulonglong get_last_insert_id() const
237 {
238 return m_diagnostics_area.last_insert_id();
239 }
240
241 /**
242 Get the total number of warnings for the last executed
243 statement. Note, that there is only one warning list even
244 if a statement returns multiple results.
245
246 @sa Documentation for C API function
247 mysql_num_warnings().
248 */
249 ulong get_warn_count() const
250 {
251 return m_diagnostics_area.warn_count();
252 }
253
254 /**
255 The following members are only valid if execute_direct()
256 or move_to_next_result() returned an error.
257 They never fail, but if they are called when there is no
258 result, or no error, the result is not defined.
259 */
260 const char *get_last_error() const { return m_diagnostics_area.message(); }
261 unsigned int get_last_errno() const { return m_diagnostics_area.sql_errno(); }
262 const char *get_last_sqlstate() const { return m_diagnostics_area.get_sqlstate(); }
263
264 /**
265 Provided get_field_count() is not 0, this never fails. You don't
266 need to free the result set, this is done automatically when
267 you advance to the next result set or destroy the connection.
268 Not returning const because of List iterator not accepting
269 Should be used when you would like Ed_connection to manage
270 result set memory for you.
271 */
272 Ed_result_set *use_result_set() { return m_current_rset; }
273 /**
274 Provided get_field_count() is not 0, this never fails. You
275 must free the returned result set. This can be called only
276 once after execute_direct().
277 Should be used when you would like to get the results
278 and destroy the connection.
279 */
280 Ed_result_set *store_result_set();
281
282 /**
283 If the query returns multiple results, this method
284 can be checked if there is another result beyond the next
285 one.
286 Never fails.
287 */
288 bool has_next_result() const { return MY_TEST(m_current_rset->m_next_rset); }
289 /**
290 Only valid to call if has_next_result() returned true.
291 Otherwise the result is undefined.
292 */
293 bool move_to_next_result()
294 {
295 m_current_rset= m_current_rset->m_next_rset;
296 return MY_TEST(m_current_rset);
297 }
298
299 ~Ed_connection() { free_old_result(); }
300private:
301 Diagnostics_area m_diagnostics_area;
302 /**
303 Execute direct interface does not support multi-statements, only
304 multi-results. So we never have a situation when we have
305 a mix of result sets and OK or error packets. We either
306 have a single result set, a single error, or a single OK,
307 or we have a series of result sets, followed by an OK or error.
308 */
309 THD *m_thd;
310 Ed_result_set *m_rsets;
311 Ed_result_set *m_current_rset;
312 friend class Protocol_local;
313private:
314 void free_old_result();
315 void add_result_set(Ed_result_set *ed_result_set);
316private:
317 Ed_connection(const Ed_connection &); /* not implemented */
318 Ed_connection &operator=(Ed_connection &); /* not implemented */
319};
320
321
322/** One result set column. */
323
324struct Ed_column: public LEX_STRING
325{
326 /** Implementation note: destructor for this class is never called. */
327};
328
329
330/** One result set record. */
331
332class Ed_row: public Sql_alloc
333{
334public:
335 const Ed_column &operator[](const unsigned int column_index) const
336 {
337 return *get_column(column_index);
338 }
339 const Ed_column *get_column(const unsigned int column_index) const
340 {
341 DBUG_ASSERT(column_index < size());
342 return m_column_array + column_index;
343 }
344 size_t size() const { return m_column_count; }
345
346 Ed_row(Ed_column *column_array_arg, size_t column_count_arg)
347 :m_column_array(column_array_arg),
348 m_column_count(column_count_arg)
349 {}
350private:
351 Ed_column *m_column_array;
352 size_t m_column_count; /* TODO: change to point to metadata */
353};
354
355#endif // SQL_PREPARE_H
356