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-1335  USA */
18 
19 #include "sql_error.h"
20 
21 
22 #define LAST_STMT_ID 0xFFFFFFFF
23 #define STMT_ID_MASK 0x7FFFFFFF
24 
25 class THD;
26 struct 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 
56 class Reprepare_observer
57 {
58 public:
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);
is_invalidated()66   bool is_invalidated() const { return m_invalidated; }
reset_reprepare_observer()67   void reset_reprepare_observer() { m_invalidated= FALSE; }
68 private:
69   bool m_invalidated;
70 };
71 
72 
73 void mysqld_stmt_prepare(THD *thd, const char *packet, uint packet_length);
74 void mysqld_stmt_execute(THD *thd, char *packet, uint packet_length);
75 void mysqld_stmt_execute_bulk(THD *thd, char *packet, uint packet_length);
76 void mysqld_stmt_bulk_execute(THD *thd, char *packet, uint packet_length);
77 void mysqld_stmt_close(THD *thd, char *packet);
78 void mysql_sql_stmt_prepare(THD *thd);
79 void mysql_sql_stmt_execute(THD *thd);
80 void mysql_sql_stmt_execute_immediate(THD *thd);
81 void mysql_sql_stmt_close(THD *thd);
82 void mysqld_stmt_fetch(THD *thd, char *packet, uint packet_length);
83 void mysqld_stmt_reset(THD *thd, char *packet);
84 void mysql_stmt_get_longdata(THD *thd, char *pos, ulong packet_length);
85 void reinit_stmt_before_use(THD *thd, LEX *lex);
86 
87 my_bool bulk_parameters_iterations(THD *thd);
88 my_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 
96 class Server_runnable
97 {
98 public:
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 
110 class 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 
118 class Ed_result_set
119 {
120 public:
121   operator List<Ed_row>&() { return *m_rows; }
size()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. */
~Ed_result_set()128   ~Ed_result_set() {}
129 
get_field_count()130   size_t get_field_count() const { return m_column_count; }
131 
new(size_t size,MEM_ROOT * mem_root)132   static void *operator new(size_t size, MEM_ROOT *mem_root)
133   { return alloc_root(mem_root, size); }
134   static void operator delete(void *ptr, size_t size) throw ();
delete(void *,MEM_ROOT *)135   static void operator delete(void *, MEM_ROOT *){}
136 private:
137   Ed_result_set(const Ed_result_set &);        /* not implemented */
138   Ed_result_set &operator=(Ed_result_set &);   /* not implemented */
139 private:
140   MEM_ROOT m_mem_root;
141   size_t m_column_count;
142   List<Ed_row> *m_rows;
143   Ed_result_set *m_next_rset;
144   friend class Ed_connection;
145 };
146 
147 
148 class Ed_connection
149 {
150 public:
151   /**
152     Construct a new "execute direct" connection.
153 
154     The connection can be used to execute SQL statements.
155     If the connection failed to initialize, the error
156     will be returned on the attempt to execute a statement.
157 
158     @pre thd  must have no open tables
159               while the connection is used. However,
160               Ed_connection works okay in LOCK TABLES mode.
161               Other properties of THD, such as the current warning
162               information, errors, etc. do not matter and are
163               preserved by Ed_connection. One thread may have many
164               Ed_connections created for it.
165   */
166   Ed_connection(THD *thd);
167 
168   /**
169     Execute one SQL statement.
170 
171     Until this method is executed, no other methods of
172     Ed_connection can be used. Life cycle of Ed_connection is:
173 
174     Initialized -> a statement has been executed ->
175     look at result, move to next result ->
176     look at result, move to next result ->
177     ...
178     moved beyond the last result == Initialized.
179 
180     This method can be called repeatedly. Once it's invoked,
181     results of the previous execution are lost.
182 
183     A result of execute_direct() can be either:
184 
185     - success, no result set rows. In this case get_field_count()
186     returns 0. This happens after execution of INSERT, UPDATE,
187     DELETE, DROP and similar statements. Some other methods, such
188     as get_affected_rows() can be used to retrieve additional
189     result information.
190 
191     - success, there are some result set rows (maybe 0). E.g.
192     happens after SELECT. In this case get_field_count() returns
193     the number of columns in a result set and store_result()
194     can be used to retrieve a result set..
195 
196     - an error, methods to retrieve error information can
197     be used.
198 
199     @return execution status
200     @retval FALSE  success, use get_field_count()
201                    to determine what to do next.
202     @retval TRUE   error, use get_last_error()
203                    to see the error number.
204   */
205   bool execute_direct(LEX_STRING sql_text);
206 
207   /**
208     Same as the previous, but takes an instance of Server_runnable
209     instead of SQL statement text.
210 
211     @return execution status
212 
213     @retval  FALSE  success, use get_field_count()
214                     if your code fragment is supposed to
215                     return a result set
216     @retval  TRUE   failure
217   */
218   bool execute_direct(Server_runnable *server_runnable);
219 
220   /**
221     Get the number of affected (deleted, updated)
222     rows for the current statement. Can be
223     used for statements with get_field_count() == 0.
224 
225     @sa Documentation for C API function
226     mysql_affected_rows().
227   */
get_affected_rows()228   ulonglong get_affected_rows() const
229   {
230     return m_diagnostics_area.affected_rows();
231   }
232 
233   /**
234     Get the last insert id, if any.
235 
236     @sa Documentation for mysql_insert_id().
237   */
get_last_insert_id()238   ulonglong get_last_insert_id() const
239   {
240     return m_diagnostics_area.last_insert_id();
241   }
242 
243   /**
244     Get the total number of warnings for the last executed
245     statement. Note, that there is only one warning list even
246     if a statement returns multiple results.
247 
248     @sa Documentation for C API function
249     mysql_num_warnings().
250   */
get_warn_count()251   ulong get_warn_count() const
252   {
253     return m_diagnostics_area.warn_count();
254   }
255 
256   /**
257     The following members are only valid if execute_direct()
258     or move_to_next_result() returned an error.
259     They never fail, but if they are called when there is no
260     result, or no error, the result is not defined.
261   */
get_last_error()262   const char *get_last_error() const { return m_diagnostics_area.message(); }
get_last_errno()263   unsigned int get_last_errno() const { return m_diagnostics_area.sql_errno(); }
get_last_sqlstate()264   const char *get_last_sqlstate() const { return m_diagnostics_area.get_sqlstate(); }
265 
266   /**
267     Provided get_field_count() is not 0, this never fails. You don't
268     need to free the result set, this is done automatically when
269     you advance to the next result set or destroy the connection.
270     Not returning const because of List iterator not accepting
271     Should be used when you would like Ed_connection to manage
272     result set memory for you.
273   */
use_result_set()274   Ed_result_set *use_result_set() { return m_current_rset; }
275   /**
276     Provided get_field_count() is not 0, this never fails. You
277     must free the returned result set. This can be called only
278     once after execute_direct().
279     Should be used when you would like to get the results
280     and destroy the connection.
281   */
282   Ed_result_set *store_result_set();
283 
284   /**
285     If the query returns multiple results, this method
286     can be checked if there is another result beyond the next
287     one.
288     Never fails.
289   */
has_next_result()290   bool has_next_result() const { return MY_TEST(m_current_rset->m_next_rset); }
291   /**
292     Only valid to call if has_next_result() returned true.
293     Otherwise the result is undefined.
294   */
move_to_next_result()295   bool move_to_next_result()
296   {
297     m_current_rset= m_current_rset->m_next_rset;
298     return MY_TEST(m_current_rset);
299   }
300 
~Ed_connection()301   ~Ed_connection() { free_old_result(); }
302 private:
303   Diagnostics_area m_diagnostics_area;
304   /**
305     Execute direct interface does not support multi-statements, only
306     multi-results. So we never have a situation when we have
307     a mix of result sets and OK or error packets. We either
308     have a single result set, a single error, or a single OK,
309     or we have a series of result sets, followed by an OK or error.
310   */
311   THD *m_thd;
312   Ed_result_set *m_rsets;
313   Ed_result_set *m_current_rset;
314   friend class Protocol_local;
315 private:
316   void free_old_result();
317   void add_result_set(Ed_result_set *ed_result_set);
318 private:
319   Ed_connection(const Ed_connection &);        /* not implemented */
320   Ed_connection &operator=(Ed_connection &);   /* not implemented */
321 };
322 
323 
324 /** One result set column. */
325 
326 struct Ed_column: public LEX_STRING
327 {
328   /** Implementation note: destructor for this class is never called. */
329 };
330 
331 
332 /** One result set record. */
333 
334 class Ed_row: public Sql_alloc
335 {
336 public:
337   const Ed_column &operator[](const unsigned int column_index) const
338   {
339     return *get_column(column_index);
340   }
get_column(const unsigned int column_index)341   const Ed_column *get_column(const unsigned int column_index) const
342   {
343     DBUG_ASSERT(column_index < size());
344     return m_column_array + column_index;
345   }
size()346   size_t size() const { return m_column_count; }
347 
Ed_row(Ed_column * column_array_arg,size_t column_count_arg)348   Ed_row(Ed_column *column_array_arg, size_t column_count_arg)
349     :m_column_array(column_array_arg),
350     m_column_count(column_count_arg)
351   {}
352 private:
353   Ed_column *m_column_array;
354   size_t m_column_count; /* TODO: change to point to metadata */
355 };
356 
357 #endif // SQL_PREPARE_H
358