~ubuntu-branches/ubuntu/trusty/mysql-5.6/trusty

« back to all changes in this revision

Viewing changes to sql/sql_prepare.h

  • Committer: Package Import Robot
  • Author(s): James Page
  • Date: 2014-02-12 11:54:27 UTC
  • Revision ID: package-import@ubuntu.com-20140212115427-oq6tfsqxl1wuwehi
Tags: upstream-5.6.15
ImportĀ upstreamĀ versionĀ 5.6.15

Show diffs side-by-side

added added

removed removed

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