~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to server/sql_parse.cc

  • Committer: Jay Pipes
  • Date: 2008-07-18 20:20:47 UTC
  • mto: This revision was merged to the branch mainline in revision 182.
  • Revision ID: jay@mysql.com-20080718202047-1tnd4i9z3k3cvg9v
DBUG entirely removed from server and client

Show diffs side-by-side

added added

removed removed

Lines of Context:
11
11
 
12
12
   You should have received a copy of the GNU General Public License
13
13
   along with this program; if not, write to the Free Software
14
 
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
15
 
 
16
 
#include <config.h>
17
 
 
18
 
#define DRIZZLE_LEX 1
19
 
 
20
 
#include <drizzled/item/num.h>
21
 
#include <drizzled/abort_exception.h>
22
 
#include <drizzled/my_hash.h>
23
 
#include <drizzled/error.h>
24
 
#include <drizzled/nested_join.h>
25
 
#include <drizzled/query_id.h>
26
 
#include <drizzled/transaction_services.h>
27
 
#include <drizzled/sql_parse.h>
28
 
#include <drizzled/data_home.h>
29
 
#include <drizzled/sql_base.h>
30
 
#include <drizzled/show.h>
31
 
#include <drizzled/function/time/unix_timestamp.h>
32
 
#include <drizzled/function/get_system_var.h>
33
 
#include <drizzled/item/cmpfunc.h>
34
 
#include <drizzled/item/null.h>
35
 
#include <drizzled/session.h>
36
 
#include <drizzled/session/cache.h>
37
 
#include <drizzled/sql_load.h>
38
 
#include <drizzled/lock.h>
39
 
#include <drizzled/select_send.h>
40
 
#include <drizzled/plugin/client.h>
41
 
#include <drizzled/statement.h>
42
 
#include <drizzled/statement/alter_table.h>
43
 
#include <drizzled/probes.h>
44
 
#include <drizzled/global_charset_info.h>
45
 
 
46
 
#include <drizzled/plugin/logging.h>
47
 
#include <drizzled/plugin/query_rewrite.h>
48
 
#include <drizzled/plugin/query_cache.h>
49
 
#include <drizzled/plugin/authorization.h>
50
 
#include <drizzled/optimizer/explain_plan.h>
51
 
#include <drizzled/pthread_globals.h>
52
 
#include <drizzled/plugin/event_observer.h>
53
 
#include <drizzled/visibility.h>
54
 
 
55
 
#include <drizzled/schema.h>
56
 
 
57
 
#include <limits.h>
58
 
 
59
 
#include <bitset>
60
 
#include <algorithm>
61
 
#include <boost/date_time.hpp>
62
 
#include <drizzled/internal/my_sys.h>
63
 
 
64
 
using namespace std;
65
 
 
66
 
extern int base_sql_parse(drizzled::Session *session); // from sql_yacc.cc
67
 
 
68
 
namespace drizzled
69
 
{
70
 
 
71
 
/* Prototypes */
72
 
bool my_yyoverflow(short **a, ParserType **b, ulong *yystacksize);
73
 
static bool parse_sql(Session *session, Lex_input_stream *lip);
74
 
void parse(Session *session, const char *inBuf, uint32_t length);
 
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
 
15
 
 
16
#define MYSQL_LEX 1
 
17
#include "mysql_priv.h"
 
18
#include "sql_repl.h"
 
19
#include "rpl_filter.h"
 
20
#include "repl_failsafe.h"
 
21
#include <m_ctype.h>
 
22
#include <myisam.h>
 
23
#include <my_dir.h>
75
24
 
76
25
/**
77
26
  @defgroup Runtime_Environment Runtime Environment
78
27
  @{
79
28
*/
80
29
 
81
 
extern size_t my_thread_stack_size;
82
 
extern const CHARSET_INFO *character_set_filesystem;
83
 
 
84
 
namespace
85
 
{
86
 
 
87
 
static const std::string command_name[COM_END+1]={
88
 
  "Sleep",
89
 
  "Quit",
90
 
  "Init DB",
91
 
  "Query",
92
 
  "Shutdown",
93
 
  "Connect",
94
 
  "Ping",
95
 
  "Error"  // Last command number
 
30
static bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables);
 
31
 
 
32
const char *any_db="*any*";     // Special symbol for check_access
 
33
 
 
34
const LEX_STRING command_name[]={
 
35
  { C_STRING_WITH_LEN("Sleep") },
 
36
  { C_STRING_WITH_LEN("Quit") },
 
37
  { C_STRING_WITH_LEN("Init DB") },
 
38
  { C_STRING_WITH_LEN("Query") },
 
39
  { C_STRING_WITH_LEN("Field List") },
 
40
  { C_STRING_WITH_LEN("Create DB") },
 
41
  { C_STRING_WITH_LEN("Drop DB") },
 
42
  { C_STRING_WITH_LEN("Refresh") },
 
43
  { C_STRING_WITH_LEN("Shutdown") },
 
44
  { C_STRING_WITH_LEN("Statistics") },
 
45
  { C_STRING_WITH_LEN("Processlist") },
 
46
  { C_STRING_WITH_LEN("Connect") },
 
47
  { C_STRING_WITH_LEN("Kill") },
 
48
  { C_STRING_WITH_LEN("Debug") },
 
49
  { C_STRING_WITH_LEN("Ping") },
 
50
  { C_STRING_WITH_LEN("Time") },
 
51
  { C_STRING_WITH_LEN("Delayed insert") },
 
52
  { C_STRING_WITH_LEN("Change user") },
 
53
  { C_STRING_WITH_LEN("Binlog Dump") },
 
54
  { C_STRING_WITH_LEN("Table Dump") },
 
55
  { C_STRING_WITH_LEN("Connect Out") },
 
56
  { C_STRING_WITH_LEN("Register Slave") },
 
57
  { C_STRING_WITH_LEN("Prepare") },
 
58
  { C_STRING_WITH_LEN("Execute") },
 
59
  { C_STRING_WITH_LEN("Long Data") },
 
60
  { C_STRING_WITH_LEN("Close stmt") },
 
61
  { C_STRING_WITH_LEN("Reset stmt") },
 
62
  { C_STRING_WITH_LEN("Set option") },
 
63
  { C_STRING_WITH_LEN("Fetch") },
 
64
  { C_STRING_WITH_LEN("Daemon") },
 
65
  { C_STRING_WITH_LEN("Error") }  // Last command number
96
66
};
97
67
 
98
 
}
99
 
 
100
68
const char *xa_state_names[]={
101
69
  "NON-EXISTING", "ACTIVE", "IDLE", "PREPARED"
102
70
};
103
71
 
 
72
static void unlock_locked_tables(THD *thd)
 
73
{
 
74
  if (thd->locked_tables)
 
75
  {
 
76
    thd->lock=thd->locked_tables;
 
77
    thd->locked_tables=0;                       // Will be automatically closed
 
78
    close_thread_tables(thd);                   // Free tables
 
79
  }
 
80
}
 
81
 
 
82
 
 
83
bool end_active_trans(THD *thd)
 
84
{
 
85
  int error=0;
 
86
  if (unlikely(thd->in_sub_stmt))
 
87
  {
 
88
    my_error(ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0));
 
89
    return(1);
 
90
  }
 
91
  if (thd->transaction.xid_state.xa_state != XA_NOTR)
 
92
  {
 
93
    my_error(ER_XAER_RMFAIL, MYF(0),
 
94
             xa_state_names[thd->transaction.xid_state.xa_state]);
 
95
    return(1);
 
96
  }
 
97
  if (thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN |
 
98
                      OPTION_TABLE_LOCK))
 
99
  {
 
100
    /* Safety if one did "drop table" on locked tables */
 
101
    if (!thd->locked_tables)
 
102
      thd->options&= ~OPTION_TABLE_LOCK;
 
103
    thd->server_status&= ~SERVER_STATUS_IN_TRANS;
 
104
    if (ha_commit(thd))
 
105
      error=1;
 
106
  }
 
107
  thd->options&= ~(OPTION_BEGIN | OPTION_KEEP_LOG);
 
108
  thd->transaction.all.modified_non_trans_table= false;
 
109
  return(error);
 
110
}
 
111
 
 
112
 
 
113
bool begin_trans(THD *thd)
 
114
{
 
115
  int error=0;
 
116
  if (unlikely(thd->in_sub_stmt))
 
117
  {
 
118
    my_error(ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0));
 
119
    return 1;
 
120
  }
 
121
  if (thd->locked_tables)
 
122
  {
 
123
    thd->lock=thd->locked_tables;
 
124
    thd->locked_tables=0;                       // Will be automatically closed
 
125
    close_thread_tables(thd);                   // Free tables
 
126
  }
 
127
  if (end_active_trans(thd))
 
128
    error= -1;
 
129
  else
 
130
  {
 
131
    LEX *lex= thd->lex;
 
132
    thd->options|= OPTION_BEGIN;
 
133
    thd->server_status|= SERVER_STATUS_IN_TRANS;
 
134
    if (lex->start_transaction_opt & MYSQL_START_TRANS_OPT_WITH_CONS_SNAPSHOT)
 
135
      error= ha_start_consistent_snapshot(thd);
 
136
  }
 
137
  return error;
 
138
}
 
139
 
 
140
/**
 
141
  Returns true if all tables should be ignored.
 
142
*/
 
143
inline bool all_tables_not_ok(THD *thd, TABLE_LIST *tables)
 
144
{
 
145
  return rpl_filter->is_on() && tables &&
 
146
         !rpl_filter->tables_ok(thd->db, tables);
 
147
}
 
148
 
 
149
 
 
150
static bool some_non_temp_table_to_be_updated(THD *thd, TABLE_LIST *tables)
 
151
{
 
152
  for (TABLE_LIST *table= tables; table; table= table->next_global)
 
153
  {
 
154
    assert(table->db && table->table_name);
 
155
    if (table->updating &&
 
156
        !find_temporary_table(thd, table->db, table->table_name))
 
157
      return 1;
 
158
  }
 
159
  return 0;
 
160
}
 
161
 
 
162
 
104
163
/**
105
164
  Mark all commands that somehow changes a table.
106
165
 
113
172
     2  - query that returns meaningful ROW_COUNT() -
114
173
          a number of modified rows
115
174
*/
116
 
bitset<CF_BIT_SIZE> sql_command_flags[SQLCOM_END+1];
117
175
 
118
 
const std::string &getCommandName(const enum_server_command& command)
119
 
{
120
 
  return command_name[command];
121
 
}
 
176
uint sql_command_flags[SQLCOM_END+1];
122
177
 
123
178
void init_update_queries(void)
124
179
{
125
 
  uint32_t x;
126
 
 
127
 
  for (x= 0; x <= SQLCOM_END; x++)
128
 
    sql_command_flags[x].reset();
 
180
  bzero((uchar*) &sql_command_flags, sizeof(sql_command_flags));
129
181
 
130
182
  sql_command_flags[SQLCOM_CREATE_TABLE]=   CF_CHANGES_DATA;
131
183
  sql_command_flags[SQLCOM_CREATE_INDEX]=   CF_CHANGES_DATA;
139
191
  sql_command_flags[SQLCOM_DROP_INDEX]=     CF_CHANGES_DATA;
140
192
 
141
193
  sql_command_flags[SQLCOM_UPDATE]=         CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
 
194
  sql_command_flags[SQLCOM_UPDATE_MULTI]=   CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
142
195
  sql_command_flags[SQLCOM_INSERT]=         CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
143
196
  sql_command_flags[SQLCOM_INSERT_SELECT]=  CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
144
197
  sql_command_flags[SQLCOM_DELETE]=         CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
 
198
  sql_command_flags[SQLCOM_DELETE_MULTI]=   CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
145
199
  sql_command_flags[SQLCOM_REPLACE]=        CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
146
200
  sql_command_flags[SQLCOM_REPLACE_SELECT]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
147
201
 
 
202
  sql_command_flags[SQLCOM_SHOW_STATUS]=      CF_STATUS_COMMAND;
 
203
  sql_command_flags[SQLCOM_SHOW_DATABASES]=   CF_STATUS_COMMAND;
 
204
  sql_command_flags[SQLCOM_SHOW_OPEN_TABLES]= CF_STATUS_COMMAND;
 
205
  sql_command_flags[SQLCOM_SHOW_FIELDS]=      CF_STATUS_COMMAND;
 
206
  sql_command_flags[SQLCOM_SHOW_KEYS]=        CF_STATUS_COMMAND;
 
207
  sql_command_flags[SQLCOM_SHOW_VARIABLES]=   CF_STATUS_COMMAND;
 
208
  sql_command_flags[SQLCOM_SHOW_CHARSETS]=    CF_STATUS_COMMAND;
 
209
  sql_command_flags[SQLCOM_SHOW_COLLATIONS]=  CF_STATUS_COMMAND;
 
210
  sql_command_flags[SQLCOM_SHOW_BINLOGS]= CF_STATUS_COMMAND;
 
211
  sql_command_flags[SQLCOM_SHOW_SLAVE_HOSTS]= CF_STATUS_COMMAND;
 
212
  sql_command_flags[SQLCOM_SHOW_BINLOG_EVENTS]= CF_STATUS_COMMAND;
148
213
  sql_command_flags[SQLCOM_SHOW_WARNS]= CF_STATUS_COMMAND;
149
214
  sql_command_flags[SQLCOM_SHOW_ERRORS]= CF_STATUS_COMMAND;
 
215
  sql_command_flags[SQLCOM_SHOW_ENGINE_STATUS]= CF_STATUS_COMMAND;
 
216
  sql_command_flags[SQLCOM_SHOW_PROCESSLIST]= CF_STATUS_COMMAND;
150
217
  sql_command_flags[SQLCOM_SHOW_CREATE_DB]=  CF_STATUS_COMMAND;
151
218
  sql_command_flags[SQLCOM_SHOW_CREATE]=  CF_STATUS_COMMAND;
 
219
  sql_command_flags[SQLCOM_SHOW_MASTER_STAT]=  CF_STATUS_COMMAND;
 
220
  sql_command_flags[SQLCOM_SHOW_SLAVE_STAT]=  CF_STATUS_COMMAND;
152
221
 
 
222
   sql_command_flags[SQLCOM_SHOW_TABLES]=       (CF_STATUS_COMMAND |
 
223
                                               CF_SHOW_TABLE_COMMAND);
 
224
  sql_command_flags[SQLCOM_SHOW_TABLE_STATUS]= (CF_STATUS_COMMAND |
 
225
                                                CF_SHOW_TABLE_COMMAND);
153
226
  /*
154
227
    The following admin table operations are allowed
155
228
    on log tables.
156
229
  */
 
230
  sql_command_flags[SQLCOM_REPAIR]=           CF_WRITE_LOGS_COMMAND;
 
231
  sql_command_flags[SQLCOM_OPTIMIZE]=         CF_WRITE_LOGS_COMMAND;
157
232
  sql_command_flags[SQLCOM_ANALYZE]=          CF_WRITE_LOGS_COMMAND;
158
233
}
159
234
 
 
235
 
 
236
bool is_update_query(enum enum_sql_command command)
 
237
{
 
238
  assert(command >= 0 && command <= SQLCOM_END);
 
239
  return (sql_command_flags[command] & CF_CHANGES_DATA) != 0;
 
240
}
 
241
 
 
242
void execute_init_command(THD *thd, sys_var_str *init_command_var,
 
243
                          rw_lock_t *var_mutex)
 
244
{
 
245
  Vio* save_vio;
 
246
  ulong save_client_capabilities;
 
247
 
 
248
  thd_proc_info(thd, "Execution of init_command");
 
249
  /*
 
250
    We need to lock init_command_var because
 
251
    during execution of init_command_var query
 
252
    values of init_command_var can't be changed
 
253
  */
 
254
  rw_rdlock(var_mutex);
 
255
  save_client_capabilities= thd->client_capabilities;
 
256
  thd->client_capabilities|= CLIENT_MULTI_QUERIES;
 
257
  /*
 
258
    We don't need return result of execution to client side.
 
259
    To forbid this we should set thd->net.vio to 0.
 
260
  */
 
261
  save_vio= thd->net.vio;
 
262
  thd->net.vio= 0;
 
263
  dispatch_command(COM_QUERY, thd,
 
264
                   init_command_var->value,
 
265
                   init_command_var->value_length);
 
266
  rw_unlock(var_mutex);
 
267
  thd->client_capabilities= save_client_capabilities;
 
268
  thd->net.vio= save_vio;
 
269
}
 
270
 
 
271
/**
 
272
  Ends the current transaction and (maybe) begin the next.
 
273
 
 
274
  @param thd            Current thread
 
275
  @param completion     Completion type
 
276
 
 
277
  @retval
 
278
    0   OK
 
279
*/
 
280
 
 
281
int end_trans(THD *thd, enum enum_mysql_completiontype completion)
 
282
{
 
283
  bool do_release= 0;
 
284
  int res= 0;
 
285
 
 
286
  if (unlikely(thd->in_sub_stmt))
 
287
  {
 
288
    my_error(ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0));
 
289
    return(1);
 
290
  }
 
291
  if (thd->transaction.xid_state.xa_state != XA_NOTR)
 
292
  {
 
293
    my_error(ER_XAER_RMFAIL, MYF(0),
 
294
             xa_state_names[thd->transaction.xid_state.xa_state]);
 
295
    return(1);
 
296
  }
 
297
  switch (completion) {
 
298
  case COMMIT:
 
299
    /*
 
300
     We don't use end_active_trans() here to ensure that this works
 
301
     even if there is a problem with the OPTION_AUTO_COMMIT flag
 
302
     (Which of course should never happen...)
 
303
    */
 
304
    thd->server_status&= ~SERVER_STATUS_IN_TRANS;
 
305
    res= ha_commit(thd);
 
306
    thd->options&= ~(OPTION_BEGIN | OPTION_KEEP_LOG);
 
307
    thd->transaction.all.modified_non_trans_table= false;
 
308
    break;
 
309
  case COMMIT_RELEASE:
 
310
    do_release= 1; /* fall through */
 
311
  case COMMIT_AND_CHAIN:
 
312
    res= end_active_trans(thd);
 
313
    if (!res && completion == COMMIT_AND_CHAIN)
 
314
      res= begin_trans(thd);
 
315
    break;
 
316
  case ROLLBACK_RELEASE:
 
317
    do_release= 1; /* fall through */
 
318
  case ROLLBACK:
 
319
  case ROLLBACK_AND_CHAIN:
 
320
  {
 
321
    thd->server_status&= ~SERVER_STATUS_IN_TRANS;
 
322
    if (ha_rollback(thd))
 
323
      res= -1;
 
324
    thd->options&= ~(OPTION_BEGIN | OPTION_KEEP_LOG);
 
325
    thd->transaction.all.modified_non_trans_table= false;
 
326
    if (!res && (completion == ROLLBACK_AND_CHAIN))
 
327
      res= begin_trans(thd);
 
328
    break;
 
329
  }
 
330
  default:
 
331
    res= -1;
 
332
    my_error(ER_UNKNOWN_COM_ERROR, MYF(0));
 
333
    return(-1);
 
334
  }
 
335
 
 
336
  if (res < 0)
 
337
    my_error(thd->killed_errno(), MYF(0));
 
338
  else if ((res == 0) && do_release)
 
339
    thd->killed= THD::KILL_CONNECTION;
 
340
 
 
341
  return(res);
 
342
}
 
343
 
 
344
 
 
345
/**
 
346
  Read one command from connection and execute it (query or simple command).
 
347
  This function is called in loop from thread function.
 
348
 
 
349
  For profiling to work, it must never be called recursively.
 
350
 
 
351
  @retval
 
352
    0  success
 
353
  @retval
 
354
    1  request of thread shutdown (see dispatch_command() description)
 
355
*/
 
356
 
 
357
bool do_command(THD *thd)
 
358
{
 
359
  bool return_value;
 
360
  char *packet= 0;
 
361
  ulong packet_length;
 
362
  NET *net= &thd->net;
 
363
  enum enum_server_command command;
 
364
 
 
365
  /*
 
366
    indicator of uninitialized lex => normal flow of errors handling
 
367
    (see my_message_sql)
 
368
  */
 
369
  thd->lex->current_select= 0;
 
370
 
 
371
  /*
 
372
    This thread will do a blocking read from the client which
 
373
    will be interrupted when the next command is received from
 
374
    the client, the connection is closed or "net_wait_timeout"
 
375
    number of seconds has passed
 
376
  */
 
377
  my_net_set_read_timeout(net, thd->variables.net_wait_timeout);
 
378
 
 
379
  /*
 
380
    XXX: this code is here only to clear possible errors of init_connect. 
 
381
    Consider moving to init_connect() instead.
 
382
  */
 
383
  thd->clear_error();                           // Clear error message
 
384
  thd->main_da.reset_diagnostics_area();
 
385
 
 
386
  net_new_transaction(net);
 
387
 
 
388
  packet_length= my_net_read(net);
 
389
  if (packet_length == packet_error)
 
390
  {
 
391
    /* Check if we can continue without closing the connection */
 
392
 
 
393
    /* The error must be set. */
 
394
    assert(thd->is_error());
 
395
    net_end_statement(thd);
 
396
 
 
397
    if (net->error != 3)
 
398
    {
 
399
      return_value= true;                       // We have to close it.
 
400
      goto out;
 
401
    }
 
402
 
 
403
    net->error= 0;
 
404
    return_value= false;
 
405
    goto out;
 
406
  }
 
407
 
 
408
  packet= (char*) net->read_pos;
 
409
  /*
 
410
    'packet_length' contains length of data, as it was stored in packet
 
411
    header. In case of malformed header, my_net_read returns zero.
 
412
    If packet_length is not zero, my_net_read ensures that the returned
 
413
    number of bytes was actually read from network.
 
414
    There is also an extra safety measure in my_net_read:
 
415
    it sets packet[packet_length]= 0, but only for non-zero packets.
 
416
  */
 
417
  if (packet_length == 0)                       /* safety */
 
418
  {
 
419
    /* Initialize with COM_SLEEP packet */
 
420
    packet[0]= (uchar) COM_SLEEP;
 
421
    packet_length= 1;
 
422
  }
 
423
  /* Do not rely on my_net_read, extra safety against programming errors. */
 
424
  packet[packet_length]= '\0';                  /* safety */
 
425
 
 
426
  command= (enum enum_server_command) (uchar) packet[0];
 
427
 
 
428
  if (command >= COM_END)
 
429
    command= COM_END;                           // Wrong command
 
430
 
 
431
  /* Restore read timeout value */
 
432
  my_net_set_read_timeout(net, thd->variables.net_read_timeout);
 
433
 
 
434
  assert(packet_length);
 
435
  return_value= dispatch_command(command, thd, packet+1, (uint) (packet_length-1));
 
436
 
 
437
out:
 
438
  return(return_value);
 
439
}
 
440
 
 
441
/**
 
442
  Determine if an attempt to update a non-temporary table while the
 
443
  read-only option was enabled has been made.
 
444
 
 
445
  This is a helper function to mysql_execute_command.
 
446
 
 
447
  @note SQLCOM_MULTI_UPDATE is an exception and dealt with elsewhere.
 
448
 
 
449
  @see mysql_execute_command
 
450
 
 
451
  @returns Status code
 
452
    @retval true The statement should be denied.
 
453
    @retval false The statement isn't updating any relevant tables.
 
454
*/
 
455
 
 
456
static my_bool deny_updates_if_read_only_option(THD *thd,
 
457
                                                TABLE_LIST *all_tables)
 
458
{
 
459
  if (!opt_readonly)
 
460
    return(false);
 
461
 
 
462
  LEX *lex= thd->lex;
 
463
 
 
464
  if (!(sql_command_flags[lex->sql_command] & CF_CHANGES_DATA))
 
465
    return(false);
 
466
 
 
467
  /* Multi update is an exception and is dealt with later. */
 
468
  if (lex->sql_command == SQLCOM_UPDATE_MULTI)
 
469
    return(false);
 
470
 
 
471
  const my_bool create_temp_tables= 
 
472
    (lex->sql_command == SQLCOM_CREATE_TABLE) &&
 
473
    (lex->create_info.options & HA_LEX_CREATE_TMP_TABLE);
 
474
 
 
475
  const my_bool drop_temp_tables= 
 
476
    (lex->sql_command == SQLCOM_DROP_TABLE) &&
 
477
    lex->drop_temporary;
 
478
 
 
479
  const my_bool update_real_tables=
 
480
    some_non_temp_table_to_be_updated(thd, all_tables) &&
 
481
    !(create_temp_tables || drop_temp_tables);
 
482
 
 
483
 
 
484
  const my_bool create_or_drop_databases=
 
485
    (lex->sql_command == SQLCOM_CREATE_DB) ||
 
486
    (lex->sql_command == SQLCOM_DROP_DB);
 
487
 
 
488
  if (update_real_tables || create_or_drop_databases)
 
489
  {
 
490
      /*
 
491
        An attempt was made to modify one or more non-temporary tables.
 
492
      */
 
493
      return(true);
 
494
  }
 
495
 
 
496
 
 
497
  /* Assuming that only temporary tables are modified. */
 
498
  return(false);
 
499
}
 
500
 
160
501
/**
161
502
  Perform one connection-level (COM_XXXX) command.
162
503
 
163
504
  @param command         type of command to perform
164
 
  @param session             connection handle
 
505
  @param thd             connection handle
165
506
  @param packet          data for the command, packet is always null-terminated
166
507
  @param packet_length   length of packet + 1 (to show that data is
167
508
                         null-terminated) except for COM_SLEEP, where it
168
509
                         can be zero.
169
510
 
170
511
  @todo
171
 
    set session->getLex()->sql_command to SQLCOM_END here.
 
512
    set thd->lex->sql_command to SQLCOM_END here.
172
513
  @todo
173
514
    The following has to be changed to an 8 byte integer
174
515
 
178
519
    1   request of thread shutdown, i. e. if command is
179
520
        COM_QUIT/COM_SHUTDOWN
180
521
*/
181
 
bool dispatch_command(enum enum_server_command command, Session *session,
182
 
                      char* packet, uint32_t packet_length)
 
522
bool dispatch_command(enum enum_server_command command, THD *thd,
 
523
                      char* packet, uint packet_length)
183
524
{
 
525
  NET *net= &thd->net;
184
526
  bool error= 0;
185
 
  Query_id &query_id= Query_id::get_query_id();
186
 
 
187
 
  DRIZZLE_COMMAND_START(session->thread_id, command);
188
 
 
189
 
  session->command= command;
190
 
  session->getLex()->sql_command= SQLCOM_END; /* to avoid confusing VIEW detectors */
191
 
  session->set_time();
192
 
  session->setQueryId(query_id.value());
 
527
 
 
528
  thd->command=command;
 
529
  /*
 
530
    Commands which always take a long time are logged into
 
531
    the slow log only if opt_log_slow_admin_statements is set.
 
532
  */
 
533
  thd->enable_slow_log= true;
 
534
  thd->lex->sql_command= SQLCOM_END; /* to avoid confusing VIEW detectors */
 
535
  thd->set_time();
 
536
  VOID(pthread_mutex_lock(&LOCK_thread_count));
 
537
  thd->query_id= global_query_id;
193
538
 
194
539
  switch( command ) {
195
540
  /* Ignore these statements. */
 
541
  case COM_STATISTICS:
196
542
  case COM_PING:
197
543
    break;
 
544
  /* Only increase id on these statements but don't count them. */
 
545
  case COM_STMT_PREPARE: 
 
546
  case COM_STMT_CLOSE:
 
547
  case COM_STMT_RESET:
 
548
    next_query_id();
 
549
    break;
198
550
  /* Increase id and count all other statements. */
199
551
  default:
200
 
    session->status_var.questions++;
201
 
    query_id.next();
202
 
  }
203
 
 
204
 
  /* @todo set session->getLex()->sql_command to SQLCOM_END here */
205
 
 
206
 
  plugin::Logging::preDo(session);
207
 
  if (unlikely(plugin::EventObserver::beforeStatement(*session)))
208
 
  {
209
 
    // We should do something about an error...
210
 
  }
211
 
 
212
 
  session->server_status&=
 
552
    statistic_increment(thd->status_var.questions, &LOCK_status);
 
553
    next_query_id();
 
554
  }
 
555
 
 
556
  thread_running++;
 
557
  /* TODO: set thd->lex->sql_command to SQLCOM_END here */
 
558
  VOID(pthread_mutex_unlock(&LOCK_thread_count));
 
559
 
 
560
  thd->server_status&=
213
561
           ~(SERVER_QUERY_NO_INDEX_USED | SERVER_QUERY_NO_GOOD_INDEX_USED);
214
562
  switch (command) {
215
563
  case COM_INIT_DB:
216
564
  {
217
 
    if (packet_length == 0)
218
 
    {
219
 
      my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
220
 
      break;
221
 
    }
222
 
 
223
 
    string tmp(packet, packet_length);
224
 
 
225
 
    identifier::Schema identifier(tmp);
226
 
 
227
 
    if (not schema::change(*session, identifier))
228
 
    {
229
 
      session->my_ok();
230
 
    }
 
565
    LEX_STRING tmp;
 
566
    status_var_increment(thd->status_var.com_stat[SQLCOM_CHANGE_DB]);
 
567
    thd->convert_string(&tmp, system_charset_info,
 
568
                        packet, packet_length, thd->charset());
 
569
    if (!mysql_change_db(thd, &tmp, false))
 
570
    {
 
571
      general_log_write(thd, command, thd->db, thd->db_length);
 
572
      my_ok(thd);
 
573
    }
 
574
    break;
 
575
  }
 
576
  case COM_REGISTER_SLAVE:
 
577
  {
 
578
    if (!register_slave(thd, (uchar*)packet, packet_length))
 
579
      my_ok(thd);
 
580
    break;
 
581
  }
 
582
  case COM_CHANGE_USER:
 
583
  {
 
584
    status_var_increment(thd->status_var.com_other);
 
585
    char *user= (char*) packet, *packet_end= packet + packet_length;
 
586
    /* Safe because there is always a trailing \0 at the end of the packet */
 
587
    char *passwd= strend(user)+1;
 
588
 
 
589
    thd->clear_error();                         // if errors from rollback
 
590
 
 
591
    /*
 
592
      Old clients send null-terminated string ('\0' for empty string) for
 
593
      password.  New clients send the size (1 byte) + string (not null
 
594
      terminated, so also '\0' for empty string).
 
595
 
 
596
      Cast *passwd to an unsigned char, so that it doesn't extend the sign
 
597
      for *passwd > 127 and become 2**32-127 after casting to uint.
 
598
    */
 
599
    char db_buff[NAME_LEN+1];                 // buffer to store db in utf8
 
600
    char *db= passwd;
 
601
    char *save_db;
 
602
    /*
 
603
      If there is no password supplied, the packet must contain '\0',
 
604
      in any type of handshake (4.1 or pre-4.1).
 
605
     */
 
606
    if (passwd >= packet_end)
 
607
    {
 
608
      my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
 
609
      break;
 
610
    }
 
611
    uint passwd_len= (thd->client_capabilities & CLIENT_SECURE_CONNECTION ?
 
612
                      (uchar)(*passwd++) : strlen(passwd));
 
613
    uint dummy_errors, save_db_length, db_length;
 
614
    int res;
 
615
    Security_context save_security_ctx= *thd->security_ctx;
 
616
    USER_CONN *save_user_connect;
 
617
 
 
618
    db+= passwd_len + 1;
 
619
    /*
 
620
      Database name is always NUL-terminated, so in case of empty database
 
621
      the packet must contain at least the trailing '\0'.
 
622
    */
 
623
    if (db >= packet_end)
 
624
    {
 
625
      my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
 
626
      break;
 
627
    }
 
628
    db_length= strlen(db);
 
629
 
 
630
    char *ptr= db + db_length + 1;
 
631
    uint cs_number= 0;
 
632
 
 
633
    if (ptr < packet_end)
 
634
    {
 
635
      if (ptr + 2 > packet_end)
 
636
      {
 
637
        my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
 
638
        break;
 
639
      }
 
640
 
 
641
      cs_number= uint2korr(ptr);
 
642
    }
 
643
 
 
644
    /* Convert database name to utf8 */
 
645
    db_buff[copy_and_convert(db_buff, sizeof(db_buff)-1,
 
646
                             system_charset_info, db, db_length,
 
647
                             thd->charset(), &dummy_errors)]= 0;
 
648
    db= db_buff;
 
649
 
 
650
    /* Save user and privileges */
 
651
    save_db_length= thd->db_length;
 
652
    save_db= thd->db;
 
653
    save_user_connect= thd->user_connect;
 
654
 
 
655
    if (!(thd->security_ctx->user= my_strdup(user, MYF(0))))
 
656
    {
 
657
      thd->security_ctx->user= save_security_ctx.user;
 
658
      my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0));
 
659
      break;
 
660
    }
 
661
 
 
662
    /* Clear variables that are allocated */
 
663
    thd->user_connect= 0;
 
664
    thd->security_ctx->priv_user= thd->security_ctx->user;
 
665
    res= check_user(thd, COM_CHANGE_USER, passwd, passwd_len, db, false);
 
666
 
 
667
    if (res)
 
668
    {
 
669
      x_free(thd->security_ctx->user);
 
670
      *thd->security_ctx= save_security_ctx;
 
671
      thd->user_connect= save_user_connect;
 
672
      thd->db= save_db;
 
673
      thd->db_length= save_db_length;
 
674
    }
 
675
    else
 
676
    {
 
677
      x_free(save_db);
 
678
      x_free(save_security_ctx.user);
 
679
 
 
680
      if (cs_number)
 
681
      {
 
682
        thd_init_client_charset(thd, cs_number);
 
683
        thd->update_charset();
 
684
      }
 
685
    }
 
686
    break;
 
687
  }
 
688
  case COM_STMT_EXECUTE:
 
689
  case COM_STMT_FETCH:
 
690
  case COM_STMT_SEND_LONG_DATA:
 
691
  case COM_STMT_PREPARE:
 
692
  case COM_STMT_CLOSE:
 
693
  case COM_STMT_RESET:
 
694
  {
 
695
    /* We should toss an error here */
231
696
    break;
232
697
  }
233
698
  case COM_QUERY:
234
699
  {
235
 
    if (not session->readAndStoreQuery(packet, packet_length))
 
700
    if (alloc_query(thd, packet, packet_length))
236
701
      break;                                    // fatal error is set
237
 
    DRIZZLE_QUERY_START(session->getQueryString()->c_str(),
238
 
                        session->thread_id,
239
 
                        const_cast<const char *>(session->schema()->c_str()));
240
 
 
241
 
    parse(session, session->getQueryString()->c_str(), session->getQueryString()->length());
242
 
 
 
702
    char *packet_end= thd->query + thd->query_length;
 
703
    const char* end_of_stmt= NULL;
 
704
 
 
705
    general_log_write(thd, command, thd->query, thd->query_length);
 
706
 
 
707
    mysql_parse(thd, thd->query, thd->query_length, &end_of_stmt);
 
708
 
 
709
    while (!thd->killed && (end_of_stmt != NULL) && ! thd->is_error())
 
710
    {
 
711
      char *beginning_of_next_stmt= (char*) end_of_stmt;
 
712
 
 
713
      net_end_statement(thd);
 
714
      /*
 
715
        Multiple queries exits, execute them individually
 
716
      */
 
717
      close_thread_tables(thd);
 
718
      ulong length= (ulong)(packet_end - beginning_of_next_stmt);
 
719
 
 
720
      log_slow_statement(thd);
 
721
 
 
722
      /* Remove garbage at start of query */
 
723
      while (length > 0 && my_isspace(thd->charset(), *beginning_of_next_stmt))
 
724
      {
 
725
        beginning_of_next_stmt++;
 
726
        length--;
 
727
      }
 
728
 
 
729
      VOID(pthread_mutex_lock(&LOCK_thread_count));
 
730
      thd->query_length= length;
 
731
      thd->query= beginning_of_next_stmt;
 
732
      /*
 
733
        Count each statement from the client.
 
734
      */
 
735
      statistic_increment(thd->status_var.questions, &LOCK_status);
 
736
      thd->query_id= next_query_id();
 
737
      thd->set_time(); /* Reset the query start time. */
 
738
      /* TODO: set thd->lex->sql_command to SQLCOM_END here */
 
739
      VOID(pthread_mutex_unlock(&LOCK_thread_count));
 
740
 
 
741
      mysql_parse(thd, beginning_of_next_stmt, length, &end_of_stmt);
 
742
    }
 
743
    break;
 
744
  }
 
745
  case COM_FIELD_LIST:                          // This isn't actually needed
 
746
  {
 
747
    char *fields, *packet_end= packet + packet_length, *arg_end;
 
748
    /* Locked closure of all tables */
 
749
    TABLE_LIST table_list;
 
750
    LEX_STRING conv_name;
 
751
 
 
752
    /* used as fields initializator */
 
753
    lex_start(thd);
 
754
 
 
755
    status_var_increment(thd->status_var.com_stat[SQLCOM_SHOW_FIELDS]);
 
756
    bzero((char*) &table_list,sizeof(table_list));
 
757
    if (thd->copy_db_to(&table_list.db, &table_list.db_length))
 
758
      break;
 
759
    /*
 
760
      We have name + wildcard in packet, separated by endzero
 
761
    */
 
762
    arg_end= strend(packet);
 
763
    thd->convert_string(&conv_name, system_charset_info,
 
764
                        packet, (uint) (arg_end - packet), thd->charset());
 
765
    table_list.alias= table_list.table_name= conv_name.str;
 
766
    packet= arg_end + 1;
 
767
 
 
768
    if (!my_strcasecmp(system_charset_info, table_list.db,
 
769
                       INFORMATION_SCHEMA_NAME.str))
 
770
    {
 
771
      ST_SCHEMA_TABLE *schema_table= find_schema_table(thd, table_list.alias);
 
772
      if (schema_table)
 
773
        table_list.schema_table= schema_table;
 
774
    }
 
775
 
 
776
    thd->query_length= (uint) (packet_end - packet); // Don't count end \0
 
777
    if (!(thd->query=fields= (char*) thd->memdup(packet,thd->query_length+1)))
 
778
      break;
 
779
    general_log_print(thd, command, "%s %s", table_list.table_name, fields);
 
780
    if (lower_case_table_names)
 
781
      my_casedn_str(files_charset_info, table_list.table_name);
 
782
 
 
783
    /* init structures for VIEW processing */
 
784
    table_list.select_lex= &(thd->lex->select_lex);
 
785
 
 
786
    lex_start(thd);
 
787
    mysql_reset_thd_for_next_command(thd);
 
788
 
 
789
    thd->lex->
 
790
      select_lex.table_list.link_in_list((uchar*) &table_list,
 
791
                                         (uchar**) &table_list.next_local);
 
792
    thd->lex->add_to_query_tables(&table_list);
 
793
 
 
794
    /* switch on VIEW optimisation: do not fill temporary tables */
 
795
    thd->lex->sql_command= SQLCOM_SHOW_FIELDS;
 
796
    mysqld_list_fields(thd,&table_list,fields);
 
797
    thd->lex->unit.cleanup();
 
798
    thd->cleanup_after_query();
243
799
    break;
244
800
  }
245
801
  case COM_QUIT:
246
802
    /* We don't calculate statistics for this command */
247
 
    session->main_da.disable_status();              // Don't send anything back
 
803
    general_log_print(thd, command, NullS);
 
804
    net->error=0;                               // Don't give 'abort' message
 
805
    thd->main_da.disable_status();              // Don't send anything back
248
806
    error=true;                                 // End server
249
807
    break;
 
808
  case COM_BINLOG_DUMP:
 
809
    {
 
810
      ulong pos;
 
811
      ushort flags;
 
812
      uint32 slave_server_id;
 
813
 
 
814
      status_var_increment(thd->status_var.com_other);
 
815
      thd->enable_slow_log= opt_log_slow_admin_statements;
 
816
      /* TODO: The following has to be changed to an 8 byte integer */
 
817
      pos = uint4korr(packet);
 
818
      flags = uint2korr(packet + 4);
 
819
      thd->server_id=0; /* avoid suicide */
 
820
      if ((slave_server_id= uint4korr(packet+6))) // mysqlbinlog.server_id==0
 
821
        kill_zombie_dump_threads(slave_server_id);
 
822
      thd->server_id = slave_server_id;
 
823
 
 
824
      general_log_print(thd, command, "Log: '%s'  Pos: %ld", packet+10,
 
825
                      (long) pos);
 
826
      mysql_binlog_send(thd, thd->strdup(packet + 10), (my_off_t) pos, flags);
 
827
      unregister_slave(thd,1,1);
 
828
      /*  fake COM_QUIT -- if we get here, the thread needs to terminate */
 
829
      error = true;
 
830
      break;
 
831
    }
250
832
  case COM_SHUTDOWN:
251
833
  {
252
 
    session->status_var.com_other++;
253
 
    session->my_eof();
254
 
    session->close_thread_tables();                     // Free before kill
255
 
    kill_drizzle();
 
834
    status_var_increment(thd->status_var.com_other);
 
835
    /*
 
836
      If the client is < 4.1.3, it is going to send us no argument; then
 
837
      packet_length is 0, packet[0] is the end 0 of the packet. Note that
 
838
      SHUTDOWN_DEFAULT is 0. If client is >= 4.1.3, the shutdown level is in
 
839
      packet[0].
 
840
    */
 
841
    enum mysql_enum_shutdown_level level=
 
842
      (enum mysql_enum_shutdown_level) (uchar) packet[0];
 
843
    if (level == SHUTDOWN_DEFAULT)
 
844
      level= SHUTDOWN_WAIT_ALL_BUFFERS; // soon default will be configurable
 
845
    else if (level != SHUTDOWN_WAIT_ALL_BUFFERS)
 
846
    {
 
847
      my_error(ER_NOT_SUPPORTED_YET, MYF(0), "this shutdown level");
 
848
      break;
 
849
    }
 
850
    general_log_print(thd, command, NullS);
 
851
    my_eof(thd);
 
852
    close_thread_tables(thd);                   // Free before kill
 
853
    kill_mysql();
256
854
    error=true;
257
855
    break;
258
856
  }
 
857
  case COM_STATISTICS:
 
858
  {
 
859
    STATUS_VAR current_global_status_var;
 
860
    ulong uptime;
 
861
    uint length;
 
862
    uint64_t queries_per_second1000;
 
863
    char buff[250];
 
864
    uint buff_len= sizeof(buff);
 
865
 
 
866
    general_log_print(thd, command, NullS);
 
867
    status_var_increment(thd->status_var.com_stat[SQLCOM_SHOW_STATUS]);
 
868
    calc_sum_of_all_status(&current_global_status_var);
 
869
    if (!(uptime= (ulong) (thd->start_time - server_start_time)))
 
870
      queries_per_second1000= 0;
 
871
    else
 
872
      queries_per_second1000= thd->query_id * 1000LL / uptime;
 
873
 
 
874
    length= snprintf((char*) buff, buff_len - 1,
 
875
                     "Uptime: %lu  Threads: %d  Questions: %lu  "
 
876
                     "Slow queries: %lu  Opens: %lu  Flush tables: %lu  "
 
877
                     "Open tables: %u  Queries per second avg: %u.%u",
 
878
                     uptime,
 
879
                     (int) thread_count, (ulong) thd->query_id,
 
880
                     current_global_status_var.long_query_count,
 
881
                     current_global_status_var.opened_tables,
 
882
                     refresh_version,
 
883
                     cached_open_tables(),
 
884
                     (uint) (queries_per_second1000 / 1000),
 
885
                     (uint) (queries_per_second1000 % 1000));
 
886
    /* Store the buffer in permanent memory */
 
887
    my_ok(thd, 0, 0, buff);
 
888
    VOID(my_net_write(net, (uchar*) buff, length));
 
889
    VOID(net_flush(net));
 
890
    thd->main_da.disable_status();
 
891
    break;
 
892
  }
259
893
  case COM_PING:
260
 
    session->status_var.com_other++;
261
 
    session->my_ok();                           // Tell client we are alive
262
 
    break;
 
894
    status_var_increment(thd->status_var.com_other);
 
895
    my_ok(thd);                         // Tell client we are alive
 
896
    break;
 
897
  case COM_PROCESS_INFO:
 
898
    status_var_increment(thd->status_var.com_stat[SQLCOM_SHOW_PROCESSLIST]);
 
899
    general_log_print(thd, command, NullS);
 
900
    mysqld_list_processes(thd, NullS, 0);
 
901
    break;
 
902
  case COM_PROCESS_KILL:
 
903
  {
 
904
    status_var_increment(thd->status_var.com_stat[SQLCOM_KILL]);
 
905
    ulong id=(ulong) uint4korr(packet);
 
906
    sql_kill(thd,id,false);
 
907
    break;
 
908
  }
 
909
  case COM_SET_OPTION:
 
910
  {
 
911
    status_var_increment(thd->status_var.com_stat[SQLCOM_SET_OPTION]);
 
912
    uint opt_command= uint2korr(packet);
 
913
 
 
914
    switch (opt_command) {
 
915
    case (int) MYSQL_OPTION_MULTI_STATEMENTS_ON:
 
916
      thd->client_capabilities|= CLIENT_MULTI_STATEMENTS;
 
917
      my_eof(thd);
 
918
      break;
 
919
    case (int) MYSQL_OPTION_MULTI_STATEMENTS_OFF:
 
920
      thd->client_capabilities&= ~CLIENT_MULTI_STATEMENTS;
 
921
      my_eof(thd);
 
922
      break;
 
923
    default:
 
924
      my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
 
925
      break;
 
926
    }
 
927
    break;
 
928
  }
263
929
  case COM_SLEEP:
264
930
  case COM_CONNECT:                             // Impossible here
 
931
  case COM_TIME:                                // Impossible from client
265
932
  case COM_END:
266
933
  default:
267
934
    my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
269
936
  }
270
937
 
271
938
  /* If commit fails, we should be able to reset the OK status. */
272
 
  session->main_da.can_overwrite_status= true;
273
 
  TransactionServices &transaction_services= TransactionServices::singleton();
274
 
  transaction_services.autocommitOrRollback(*session, session->is_error());
275
 
  session->main_da.can_overwrite_status= false;
 
939
  thd->main_da.can_overwrite_status= true;
 
940
  ha_autocommit_or_rollback(thd, thd->is_error());
 
941
  thd->main_da.can_overwrite_status= false;
276
942
 
277
 
  session->transaction.stmt.reset();
 
943
  thd->transaction.stmt.reset();
278
944
 
279
945
 
280
946
  /* report error issued during command execution */
281
 
  if (session->killed_errno())
282
 
  {
283
 
    if (! session->main_da.is_set())
284
 
      session->send_kill_message();
285
 
  }
286
 
  if (session->getKilled() == Session::KILL_QUERY || session->getKilled() == Session::KILL_BAD_DATA)
287
 
  {
288
 
    session->setKilled(Session::NOT_KILLED);
289
 
    session->setAbort(false);
290
 
  }
291
 
 
292
 
  /* Can not be true, but do not take chances in production. */
293
 
  assert(! session->main_da.is_sent);
294
 
 
295
 
  switch (session->main_da.status())
296
 
  {
297
 
  case Diagnostics_area::DA_ERROR:
298
 
    /* The query failed, send error to log and abort bootstrap. */
299
 
    session->getClient()->sendError(session->main_da.sql_errno(),
300
 
                               session->main_da.message());
301
 
    break;
302
 
 
303
 
  case Diagnostics_area::DA_EOF:
304
 
    session->getClient()->sendEOF();
305
 
    break;
306
 
 
307
 
  case Diagnostics_area::DA_OK:
308
 
    session->getClient()->sendOK();
309
 
    break;
310
 
 
311
 
  case Diagnostics_area::DA_DISABLED:
312
 
    break;
313
 
 
314
 
  case Diagnostics_area::DA_EMPTY:
315
 
  default:
316
 
    session->getClient()->sendOK();
317
 
    break;
318
 
  }
319
 
 
320
 
  session->main_da.is_sent= true;
321
 
 
322
 
  session->set_proc_info("closing tables");
 
947
  if (thd->killed_errno())
 
948
  {
 
949
    if (! thd->main_da.is_set())
 
950
      thd->send_kill_message();
 
951
  }
 
952
  if (thd->killed == THD::KILL_QUERY || thd->killed == THD::KILL_BAD_DATA)
 
953
  {
 
954
    thd->killed= THD::NOT_KILLED;
 
955
    thd->mysys_var->abort= 0;
 
956
  }
 
957
 
 
958
  net_end_statement(thd);
 
959
 
 
960
  thd->proc_info= "closing tables";
323
961
  /* Free tables */
324
 
  session->close_thread_tables();
325
 
 
326
 
  plugin::Logging::postDo(session);
327
 
  if (unlikely(plugin::EventObserver::afterStatement(*session)))
328
 
  {
329
 
    // We should do something about an error...
330
 
  }
331
 
 
332
 
  /* Store temp state for processlist */
333
 
  session->set_proc_info("cleaning up");
334
 
  session->command= COM_SLEEP;
335
 
  session->resetQueryString();
336
 
 
337
 
  session->set_proc_info(NULL);
338
 
  session->mem_root->free_root(MYF(memory::KEEP_PREALLOC));
339
 
 
340
 
  if (DRIZZLE_QUERY_DONE_ENABLED() || DRIZZLE_COMMAND_DONE_ENABLED())
341
 
  {
342
 
    if (command == COM_QUERY)
 
962
  close_thread_tables(thd);
 
963
 
 
964
  log_slow_statement(thd);
 
965
 
 
966
  thd_proc_info(thd, "cleaning up");
 
967
  VOID(pthread_mutex_lock(&LOCK_thread_count)); // For process list
 
968
  thd_proc_info(thd, 0);
 
969
  thd->command=COM_SLEEP;
 
970
  thd->query=0;
 
971
  thd->query_length=0;
 
972
  thread_running--;
 
973
  VOID(pthread_mutex_unlock(&LOCK_thread_count));
 
974
  thd->packet.shrink(thd->variables.net_buffer_length); // Reclaim some memory
 
975
  free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
 
976
  return(error);
 
977
}
 
978
 
 
979
 
 
980
void log_slow_statement(THD *thd)
 
981
{
 
982
  /*
 
983
    The following should never be true with our current code base,
 
984
    but better to keep this here so we don't accidently try to log a
 
985
    statement in a trigger or stored function
 
986
  */
 
987
  if (unlikely(thd->in_sub_stmt))
 
988
    return;                           // Don't set time for sub stmt
 
989
 
 
990
  /*
 
991
    Do not log administrative statements unless the appropriate option is
 
992
    set; do not log into slow log if reading from backup.
 
993
  */
 
994
  if (thd->enable_slow_log && !thd->user_time)
 
995
  {
 
996
    thd_proc_info(thd, "logging slow query");
 
997
    uint64_t end_utime_of_query= thd->current_utime();
 
998
 
 
999
    if (((end_utime_of_query - thd->utime_after_lock) >
 
1000
         thd->variables.long_query_time ||
 
1001
         ((thd->server_status &
 
1002
           (SERVER_QUERY_NO_INDEX_USED | SERVER_QUERY_NO_GOOD_INDEX_USED)) &&
 
1003
          opt_log_queries_not_using_indexes &&
 
1004
           !(sql_command_flags[thd->lex->sql_command] & CF_STATUS_COMMAND))) &&
 
1005
        thd->examined_row_count >= thd->variables.min_examined_row_limit)
343
1006
    {
344
 
      DRIZZLE_QUERY_DONE(session->is_error());
 
1007
      thd_proc_info(thd, "logging slow query");
 
1008
      thd->status_var.long_query_count++;
 
1009
      slow_log_print(thd, thd->query, thd->query_length, end_utime_of_query);
345
1010
    }
346
 
    DRIZZLE_COMMAND_DONE(session->is_error());
347
1011
  }
348
 
 
349
 
  return error;
 
1012
  return;
350
1013
}
351
1014
 
352
1015
 
353
1016
/**
354
 
  Create a TableList object for an INFORMATION_SCHEMA table.
 
1017
  Create a TABLE_LIST object for an INFORMATION_SCHEMA table.
355
1018
 
356
1019
    This function is used in the parser to convert a SHOW or DESCRIBE
357
1020
    table_name command to a SELECT from INFORMATION_SCHEMA.
358
 
    It prepares a Select_Lex and a TableList object to represent the
 
1021
    It prepares a SELECT_LEX and a TABLE_LIST object to represent the
359
1022
    given command as a SELECT parse tree.
360
1023
 
361
 
  @param session           thread handle
362
 
  @param lex               current lex
363
 
  @param table_ident       table alias if it's used
364
 
  @param schema_table_name the name of the INFORMATION_SCHEMA table to be
365
 
                           created
 
1024
  @param thd              thread handle
 
1025
  @param lex              current lex
 
1026
  @param table_ident      table alias if it's used
 
1027
  @param schema_table_idx the type of the INFORMATION_SCHEMA table to be
 
1028
                          created
366
1029
 
367
1030
  @note
368
1031
    Due to the way this function works with memory and LEX it cannot
375
1038
    1                 out of memory or SHOW commands are not allowed
376
1039
                      in this version of the server.
377
1040
*/
378
 
static bool _schema_select(Session *session, Select_Lex *sel,
379
 
                           const string& schema_table_name)
 
1041
 
 
1042
int prepare_schema_table(THD *thd, LEX *lex, Table_ident *table_ident,
 
1043
                         enum enum_schema_tables schema_table_idx)
380
1044
{
381
 
  LEX_STRING db, table;
382
 
  bitset<NUM_OF_TABLE_OPTIONS> table_options;
383
 
  /*
384
 
     We have to make non const db_name & table_name
385
 
     because of lower_case_table_names
386
 
  */
387
 
  session->make_lex_string(&db, "data_dictionary", sizeof("data_dictionary"), false);
388
 
  session->make_lex_string(&table, schema_table_name, false);
389
 
 
390
 
  if (! sel->add_table_to_list(session, new Table_ident(db, table),
391
 
                               NULL, table_options, TL_READ))
 
1045
  SELECT_LEX *schema_select_lex= NULL;
 
1046
 
 
1047
  switch (schema_table_idx) {
 
1048
  case SCH_SCHEMATA:
 
1049
    break;
 
1050
  case SCH_TABLE_NAMES:
 
1051
  case SCH_TABLES:
 
1052
    {
 
1053
      LEX_STRING db;
 
1054
      size_t dummy;
 
1055
      if (lex->select_lex.db == NULL &&
 
1056
          lex->copy_db_to(&lex->select_lex.db, &dummy))
 
1057
      {
 
1058
        return(1);
 
1059
      }
 
1060
      schema_select_lex= new SELECT_LEX();
 
1061
      db.str= schema_select_lex->db= lex->select_lex.db;
 
1062
      schema_select_lex->table_list.first= NULL;
 
1063
      db.length= strlen(db.str);
 
1064
 
 
1065
      if (check_db_name(&db))
 
1066
      {
 
1067
        my_error(ER_WRONG_DB_NAME, MYF(0), db.str);
 
1068
        return(1);
 
1069
      }
 
1070
      break;
 
1071
    }
 
1072
  case SCH_COLUMNS:
 
1073
  case SCH_STATISTICS:
392
1074
  {
393
 
    return true;
394
 
  }
395
 
  return false;
396
 
}
397
 
 
398
 
int prepare_new_schema_table(Session *session, LEX *lex,
399
 
                             const string& schema_table_name)
400
 
{
401
 
  Select_Lex *schema_select_lex= NULL;
402
 
 
403
 
  Select_Lex *select_lex= lex->current_select;
 
1075
    assert(table_ident);
 
1076
    TABLE_LIST **query_tables_last= lex->query_tables_last;
 
1077
    schema_select_lex= new SELECT_LEX();
 
1078
    /* 'parent_lex' is used in init_query() so it must be before it. */
 
1079
    schema_select_lex->parent_lex= lex;
 
1080
    schema_select_lex->init_query();
 
1081
    if (!schema_select_lex->add_table_to_list(thd, table_ident, 0, 0, TL_READ))
 
1082
      return(1);
 
1083
    lex->query_tables_last= query_tables_last;
 
1084
    break;
 
1085
  }
 
1086
  case SCH_OPEN_TABLES:
 
1087
  case SCH_VARIABLES:
 
1088
  case SCH_STATUS:
 
1089
  case SCH_CHARSETS:
 
1090
  case SCH_COLLATIONS:
 
1091
  case SCH_COLLATION_CHARACTER_SET_APPLICABILITY:
 
1092
  case SCH_TABLE_CONSTRAINTS:
 
1093
  case SCH_KEY_COLUMN_USAGE:
 
1094
  default:
 
1095
    break;
 
1096
  }
 
1097
  
 
1098
  SELECT_LEX *select_lex= lex->current_select;
404
1099
  assert(select_lex);
405
 
  if (_schema_select(session, select_lex, schema_table_name))
 
1100
  if (make_schema_select(thd, select_lex, schema_table_idx))
406
1101
  {
407
1102
    return(1);
408
1103
  }
409
 
  TableList *table_list= (TableList*) select_lex->table_list.first;
 
1104
  TABLE_LIST *table_list= (TABLE_LIST*) select_lex->table_list.first;
410
1105
  assert(table_list);
411
1106
  table_list->schema_select_lex= schema_select_lex;
412
 
 
413
 
  return 0;
414
 
}
415
 
 
416
 
/**
417
 
  Execute command saved in session and lex->sql_command.
 
1107
  table_list->schema_table_reformed= 1;
 
1108
  return(0);
 
1109
}
 
1110
 
 
1111
 
 
1112
/**
 
1113
  Read query from packet and store in thd->query.
 
1114
  Used in COM_QUERY and COM_STMT_PREPARE.
 
1115
 
 
1116
    Sets the following THD variables:
 
1117
  - query
 
1118
  - query_length
 
1119
 
 
1120
  @retval
 
1121
    false ok
 
1122
  @retval
 
1123
    true  error;  In this case thd->fatal_error is set
 
1124
*/
 
1125
 
 
1126
bool alloc_query(THD *thd, const char *packet, uint packet_length)
 
1127
{
 
1128
  /* Remove garbage at start and end of query */
 
1129
  while (packet_length > 0 && my_isspace(thd->charset(), packet[0]))
 
1130
  {
 
1131
    packet++;
 
1132
    packet_length--;
 
1133
  }
 
1134
  const char *pos= packet + packet_length;     // Point at end null
 
1135
  while (packet_length > 0 &&
 
1136
         (pos[-1] == ';' || my_isspace(thd->charset() ,pos[-1])))
 
1137
  {
 
1138
    pos--;
 
1139
    packet_length--;
 
1140
  }
 
1141
  /* We must allocate some extra memory for query cache */
 
1142
  thd->query_length= 0;                        // Extra safety: Avoid races
 
1143
  if (!(thd->query= (char*) thd->memdup_w_gap((uchar*) (packet),
 
1144
                                              packet_length,
 
1145
                                              thd->db_length+ 1)))
 
1146
    return true;
 
1147
  thd->query[packet_length]=0;
 
1148
  thd->query_length= packet_length;
 
1149
 
 
1150
  /* Reclaim some memory */
 
1151
  thd->packet.shrink(thd->variables.net_buffer_length);
 
1152
  thd->convert_buffer.shrink(thd->variables.net_buffer_length);
 
1153
 
 
1154
  return false;
 
1155
}
 
1156
 
 
1157
static void reset_one_shot_variables(THD *thd) 
 
1158
{
 
1159
  thd->variables.character_set_client=
 
1160
    global_system_variables.character_set_client;
 
1161
  thd->variables.collation_connection=
 
1162
    global_system_variables.collation_connection;
 
1163
  thd->variables.collation_database=
 
1164
    global_system_variables.collation_database;
 
1165
  thd->variables.collation_server=
 
1166
    global_system_variables.collation_server;
 
1167
  thd->update_charset();
 
1168
  thd->variables.time_zone=
 
1169
    global_system_variables.time_zone;
 
1170
  thd->variables.lc_time_names= &my_locale_en_US;
 
1171
  thd->one_shot_set= 0;
 
1172
}
 
1173
 
 
1174
 
 
1175
/**
 
1176
  Execute command saved in thd and lex->sql_command.
418
1177
 
419
1178
    Before every operation that can request a write lock for a table
420
1179
    wait if a global read lock exists. However do not wait if this
426
1185
    global read lock when it succeeds. This needs to be released by
427
1186
    start_waiting_global_read_lock() after the operation.
428
1187
 
429
 
  @param session                       Thread handle
 
1188
  @param thd                       Thread handle
430
1189
 
431
1190
  @todo
432
1191
    - Invalidate the table in the query cache if something changed
443
1202
    true        Error
444
1203
*/
445
1204
 
446
 
static int execute_command(Session *session)
 
1205
int
 
1206
mysql_execute_command(THD *thd)
447
1207
{
448
 
  bool res= false;
449
 
 
450
 
  /* first Select_Lex (have special meaning for many of non-SELECTcommands) */
451
 
  Select_Lex *select_lex= &session->getLex()->select_lex;
452
 
 
 
1208
  int res= false;
 
1209
  bool need_start_waiting= false; // have protection against global read lock
 
1210
  int  up_result= 0;
 
1211
  LEX  *lex= thd->lex;
 
1212
  /* first SELECT_LEX (have special meaning for many of non-SELECTcommands) */
 
1213
  SELECT_LEX *select_lex= &lex->select_lex;
 
1214
  /* first table of first SELECT_LEX */
 
1215
  TABLE_LIST *first_table= (TABLE_LIST*) select_lex->table_list.first;
453
1216
  /* list of all tables in query */
454
 
  TableList *all_tables;
 
1217
  TABLE_LIST *all_tables;
 
1218
  /* most outer SELECT_LEX_UNIT of query */
 
1219
  SELECT_LEX_UNIT *unit= &lex->unit;
 
1220
  /* Saved variable value */
455
1221
 
456
1222
  /*
457
 
    In many cases first table of main Select_Lex have special meaning =>
458
 
    check that it is first table in global list and relink it first in
 
1223
    In many cases first table of main SELECT_LEX have special meaning =>
 
1224
    check that it is first table in global list and relink it first in 
459
1225
    queries_tables list if it is necessary (we need such relinking only
460
1226
    for queries with subqueries in select list, in this case tables of
461
1227
    subqueries will go to global list first)
462
1228
 
463
 
    all_tables will differ from first_table only if most upper Select_Lex
 
1229
    all_tables will differ from first_table only if most upper SELECT_LEX
464
1230
    do not contain tables.
465
1231
 
466
1232
    Because of above in place where should be at least one table in most
467
 
    outer Select_Lex we have following check:
 
1233
    outer SELECT_LEX we have following check:
468
1234
    assert(first_table == all_tables);
469
1235
    assert(first_table == all_tables && first_table != 0);
470
1236
  */
471
 
  session->getLex()->first_lists_tables_same();
472
 
 
 
1237
  lex->first_lists_tables_same();
473
1238
  /* should be assigned after making first tables same */
474
 
  all_tables= session->getLex()->query_tables;
475
 
 
 
1239
  all_tables= lex->query_tables;
476
1240
  /* set context for commands which do not use setup_tables */
477
 
  select_lex->context.resolve_in_table_list_only((TableList*)select_lex->table_list.first);
 
1241
  select_lex->
 
1242
    context.resolve_in_table_list_only((TABLE_LIST*)select_lex->
 
1243
                                       table_list.first);
478
1244
 
479
1245
  /*
480
1246
    Reset warning count for each query that uses tables
483
1249
    variables, but for now this is probably good enough.
484
1250
    Don't reset warnings when executing a stored routine.
485
1251
  */
486
 
  if (all_tables || ! session->getLex()->is_single_level_stmt())
487
 
  {
488
 
    drizzle_reset_errors(session, 0);
489
 
  }
490
 
 
491
 
  assert(session->transaction.stmt.hasModifiedNonTransData() == false);
492
 
 
493
 
  if (! (session->server_status & SERVER_STATUS_AUTOCOMMIT)
494
 
      && ! session->inTransaction()
495
 
      && session->getLex()->statement->isTransactional())
496
 
  {
497
 
    if (session->startTransaction() == false)
498
 
    {
499
 
      my_error(drizzled::ER_UNKNOWN_ERROR, MYF(0));
500
 
      return true;
501
 
    }
502
 
  }
503
 
 
504
 
  /* now we are ready to execute the statement */
505
 
  res= session->getLex()->statement->execute();
506
 
  session->set_proc_info("query end");
 
1252
  if (all_tables || !lex->is_single_level_stmt())
 
1253
    mysql_reset_errors(thd, 0);
 
1254
 
 
1255
  if (unlikely(thd->slave_thread))
 
1256
  {
 
1257
    /*
 
1258
      Check if statment should be skipped because of slave filtering
 
1259
      rules
 
1260
 
 
1261
      Exceptions are:
 
1262
      - UPDATE MULTI: For this statement, we want to check the filtering
 
1263
        rules later in the code
 
1264
      - SET: we always execute it (Not that many SET commands exists in
 
1265
        the binary log anyway -- only 4.1 masters write SET statements,
 
1266
        in 5.0 there are no SET statements in the binary log)
 
1267
      - DROP TEMPORARY TABLE IF EXISTS: we always execute it (otherwise we
 
1268
        have stale files on slave caused by exclusion of one tmp table).
 
1269
    */
 
1270
    if (!(lex->sql_command == SQLCOM_UPDATE_MULTI) &&
 
1271
        !(lex->sql_command == SQLCOM_SET_OPTION) &&
 
1272
        !(lex->sql_command == SQLCOM_DROP_TABLE &&
 
1273
          lex->drop_temporary && lex->drop_if_exists) &&
 
1274
        all_tables_not_ok(thd, all_tables))
 
1275
    {
 
1276
      /* we warn the slave SQL thread */
 
1277
      my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0));
 
1278
      if (thd->one_shot_set)
 
1279
      {
 
1280
        /*
 
1281
          It's ok to check thd->one_shot_set here:
 
1282
 
 
1283
          The charsets in a MySQL 5.0 slave can change by both a binlogged
 
1284
          SET ONE_SHOT statement and the event-internal charset setting, 
 
1285
          and these two ways to change charsets do not seems to work
 
1286
          together.
 
1287
 
 
1288
          At least there seems to be problems in the rli cache for
 
1289
          charsets if we are using ONE_SHOT.  Note that this is normally no
 
1290
          problem because either the >= 5.0 slave reads a 4.1 binlog (with
 
1291
          ONE_SHOT) *or* or 5.0 binlog (without ONE_SHOT) but never both."
 
1292
        */
 
1293
        reset_one_shot_variables(thd);
 
1294
      }
 
1295
      return(0);
 
1296
    }
 
1297
  }
 
1298
  else
 
1299
  {
 
1300
    /*
 
1301
      When option readonly is set deny operations which change non-temporary
 
1302
      tables. Except for the replication thread and the 'super' users.
 
1303
    */
 
1304
    if (deny_updates_if_read_only_option(thd, all_tables))
 
1305
    {
 
1306
      my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--read-only");
 
1307
      return(-1);
 
1308
    }
 
1309
  } /* endif unlikely slave */
 
1310
  status_var_increment(thd->status_var.com_stat[lex->sql_command]);
 
1311
 
 
1312
  assert(thd->transaction.stmt.modified_non_trans_table == false);
 
1313
  
 
1314
  switch (lex->sql_command) {
 
1315
  case SQLCOM_SHOW_STATUS:
 
1316
  {
 
1317
    system_status_var old_status_var= thd->status_var;
 
1318
    thd->initial_status_var= &old_status_var;
 
1319
    res= execute_sqlcom_select(thd, all_tables);
 
1320
    /* Don't log SHOW STATUS commands to slow query log */
 
1321
    thd->server_status&= ~(SERVER_QUERY_NO_INDEX_USED |
 
1322
                           SERVER_QUERY_NO_GOOD_INDEX_USED);
 
1323
    /*
 
1324
      restore status variables, as we don't want 'show status' to cause
 
1325
      changes
 
1326
    */
 
1327
    pthread_mutex_lock(&LOCK_status);
 
1328
    add_diff_to_status(&global_status_var, &thd->status_var,
 
1329
                       &old_status_var);
 
1330
    thd->status_var= old_status_var;
 
1331
    pthread_mutex_unlock(&LOCK_status);
 
1332
    break;
 
1333
  }
 
1334
  case SQLCOM_SHOW_DATABASES:
 
1335
  case SQLCOM_SHOW_TABLES:
 
1336
  case SQLCOM_SHOW_TABLE_STATUS:
 
1337
  case SQLCOM_SHOW_OPEN_TABLES:
 
1338
  case SQLCOM_SHOW_FIELDS:
 
1339
  case SQLCOM_SHOW_KEYS:
 
1340
  case SQLCOM_SHOW_VARIABLES:
 
1341
  case SQLCOM_SHOW_CHARSETS:
 
1342
  case SQLCOM_SHOW_COLLATIONS:
 
1343
  case SQLCOM_SELECT:
 
1344
  {
 
1345
    thd->status_var.last_query_cost= 0.0;
 
1346
    res= execute_sqlcom_select(thd, all_tables);
 
1347
    break;
 
1348
  }
 
1349
  case SQLCOM_EMPTY_QUERY:
 
1350
    my_ok(thd);
 
1351
    break;
 
1352
 
 
1353
  case SQLCOM_PURGE:
 
1354
  {
 
1355
    res = purge_master_logs(thd, lex->to_log);
 
1356
    break;
 
1357
  }
 
1358
  case SQLCOM_PURGE_BEFORE:
 
1359
  {
 
1360
    Item *it;
 
1361
 
 
1362
    /* PURGE MASTER LOGS BEFORE 'data' */
 
1363
    it= (Item *)lex->value_list.head();
 
1364
    if ((!it->fixed && it->fix_fields(lex->thd, &it)) ||
 
1365
        it->check_cols(1))
 
1366
    {
 
1367
      my_error(ER_WRONG_ARGUMENTS, MYF(0), "PURGE LOGS BEFORE");
 
1368
      goto error;
 
1369
    }
 
1370
    it= new Item_func_unix_timestamp(it);
 
1371
    /*
 
1372
      it is OK only emulate fix_fieds, because we need only
 
1373
      value of constant
 
1374
    */
 
1375
    it->quick_fix_field();
 
1376
    res = purge_master_logs_before_date(thd, (ulong)it->val_int());
 
1377
    break;
 
1378
  }
 
1379
  case SQLCOM_SHOW_WARNS:
 
1380
  {
 
1381
    res= mysqld_show_warnings(thd, (ulong)
 
1382
                              ((1L << (uint) MYSQL_ERROR::WARN_LEVEL_NOTE) |
 
1383
                               (1L << (uint) MYSQL_ERROR::WARN_LEVEL_WARN) |
 
1384
                               (1L << (uint) MYSQL_ERROR::WARN_LEVEL_ERROR)
 
1385
                               ));
 
1386
    break;
 
1387
  }
 
1388
  case SQLCOM_SHOW_ERRORS:
 
1389
  {
 
1390
    res= mysqld_show_warnings(thd, (ulong)
 
1391
                              (1L << (uint) MYSQL_ERROR::WARN_LEVEL_ERROR));
 
1392
    break;
 
1393
  }
 
1394
  case SQLCOM_SHOW_SLAVE_HOSTS:
 
1395
  {
 
1396
    res = show_slave_hosts(thd);
 
1397
    break;
 
1398
  }
 
1399
  case SQLCOM_SHOW_BINLOG_EVENTS:
 
1400
  {
 
1401
    res = mysql_show_binlog_events(thd);
 
1402
    break;
 
1403
  }
 
1404
 
 
1405
  case SQLCOM_ASSIGN_TO_KEYCACHE:
 
1406
  {
 
1407
    assert(first_table == all_tables && first_table != 0);
 
1408
    res= mysql_assign_to_keycache(thd, first_table, &lex->ident);
 
1409
    break;
 
1410
  }
 
1411
  case SQLCOM_CHANGE_MASTER:
 
1412
  {
 
1413
    pthread_mutex_lock(&LOCK_active_mi);
 
1414
    res = change_master(thd,active_mi);
 
1415
    pthread_mutex_unlock(&LOCK_active_mi);
 
1416
    break;
 
1417
  }
 
1418
  case SQLCOM_SHOW_SLAVE_STAT:
 
1419
  {
 
1420
    pthread_mutex_lock(&LOCK_active_mi);
 
1421
    if (active_mi != NULL)
 
1422
    {
 
1423
      res = show_master_info(thd, active_mi);
 
1424
    }
 
1425
    else
 
1426
    {
 
1427
      push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, 0,
 
1428
                   "the master info structure does not exist");
 
1429
      my_ok(thd);
 
1430
    }
 
1431
    pthread_mutex_unlock(&LOCK_active_mi);
 
1432
    break;
 
1433
  }
 
1434
  case SQLCOM_SHOW_MASTER_STAT:
 
1435
  {
 
1436
    res = show_binlog_info(thd);
 
1437
    break;
 
1438
  }
 
1439
 
 
1440
  case SQLCOM_SHOW_ENGINE_STATUS:
 
1441
    {
 
1442
      res = ha_show_status(thd, lex->create_info.db_type, HA_ENGINE_STATUS);
 
1443
      break;
 
1444
    }
 
1445
  case SQLCOM_CREATE_TABLE:
 
1446
  {
 
1447
    /* If CREATE TABLE of non-temporary table, do implicit commit */
 
1448
    if (!(lex->create_info.options & HA_LEX_CREATE_TMP_TABLE))
 
1449
    {
 
1450
      if (end_active_trans(thd))
 
1451
      {
 
1452
        res= -1;
 
1453
        break;
 
1454
      }
 
1455
    }
 
1456
    assert(first_table == all_tables && first_table != 0);
 
1457
    bool link_to_local;
 
1458
    // Skip first table, which is the table we are creating
 
1459
    TABLE_LIST *create_table= lex->unlink_first_table(&link_to_local);
 
1460
    TABLE_LIST *select_tables= lex->query_tables;
 
1461
    /*
 
1462
      Code below (especially in mysql_create_table() and select_create
 
1463
      methods) may modify HA_CREATE_INFO structure in LEX, so we have to
 
1464
      use a copy of this structure to make execution prepared statement-
 
1465
      safe. A shallow copy is enough as this code won't modify any memory
 
1466
      referenced from this structure.
 
1467
    */
 
1468
    HA_CREATE_INFO create_info(lex->create_info);
 
1469
    /*
 
1470
      We need to copy alter_info for the same reasons of re-execution
 
1471
      safety, only in case of Alter_info we have to do (almost) a deep
 
1472
      copy.
 
1473
    */
 
1474
    Alter_info alter_info(lex->alter_info, thd->mem_root);
 
1475
 
 
1476
    if (thd->is_fatal_error)
 
1477
    {
 
1478
      /* If out of memory when creating a copy of alter_info. */
 
1479
      res= 1;
 
1480
      goto end_with_restore_list;
 
1481
    }
 
1482
 
 
1483
    if ((res= create_table_precheck(thd, select_tables, create_table)))
 
1484
      goto end_with_restore_list;
 
1485
 
 
1486
    /* Might have been updated in create_table_precheck */
 
1487
    create_info.alias= create_table->alias;
 
1488
 
 
1489
#ifdef HAVE_READLINK
 
1490
    /* Fix names if symlinked tables */
 
1491
    if (append_file_to_dir(thd, &create_info.data_file_name,
 
1492
                           create_table->table_name) ||
 
1493
        append_file_to_dir(thd, &create_info.index_file_name,
 
1494
                           create_table->table_name))
 
1495
      goto end_with_restore_list;
 
1496
#endif
 
1497
    /*
 
1498
      If we are using SET CHARSET without DEFAULT, add an implicit
 
1499
      DEFAULT to not confuse old users. (This may change).
 
1500
    */
 
1501
    if ((create_info.used_fields &
 
1502
         (HA_CREATE_USED_DEFAULT_CHARSET | HA_CREATE_USED_CHARSET)) ==
 
1503
        HA_CREATE_USED_CHARSET)
 
1504
    {
 
1505
      create_info.used_fields&= ~HA_CREATE_USED_CHARSET;
 
1506
      create_info.used_fields|= HA_CREATE_USED_DEFAULT_CHARSET;
 
1507
      create_info.default_table_charset= create_info.table_charset;
 
1508
      create_info.table_charset= 0;
 
1509
    }
 
1510
    /*
 
1511
      The create-select command will open and read-lock the select table
 
1512
      and then create, open and write-lock the new table. If a global
 
1513
      read lock steps in, we get a deadlock. The write lock waits for
 
1514
      the global read lock, while the global read lock waits for the
 
1515
      select table to be closed. So we wait until the global readlock is
 
1516
      gone before starting both steps. Note that
 
1517
      wait_if_global_read_lock() sets a protection against a new global
 
1518
      read lock when it succeeds. This needs to be released by
 
1519
      start_waiting_global_read_lock(). We protect the normal CREATE
 
1520
      TABLE in the same way. That way we avoid that a new table is
 
1521
      created during a gobal read lock.
 
1522
    */
 
1523
    if (!thd->locked_tables &&
 
1524
        !(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
 
1525
    {
 
1526
      res= 1;
 
1527
      goto end_with_restore_list;
 
1528
    }
 
1529
    if (select_lex->item_list.elements)         // With select
 
1530
    {
 
1531
      select_result *result;
 
1532
 
 
1533
      select_lex->options|= SELECT_NO_UNLOCK;
 
1534
      unit->set_limit(select_lex);
 
1535
 
 
1536
      /*
 
1537
        Disable non-empty MERGE tables with CREATE...SELECT. Too
 
1538
        complicated. See Bug #26379. Empty MERGE tables are read-only
 
1539
        and don't allow CREATE...SELECT anyway.
 
1540
      */
 
1541
      if (create_info.used_fields & HA_CREATE_USED_UNION)
 
1542
      {
 
1543
        my_error(ER_WRONG_OBJECT, MYF(0), create_table->db,
 
1544
                 create_table->table_name, "BASE TABLE");
 
1545
        res= 1;
 
1546
        goto end_with_restore_list;
 
1547
      }
 
1548
 
 
1549
      if (!(create_info.options & HA_LEX_CREATE_TMP_TABLE))
 
1550
      {
 
1551
        lex->link_first_table_back(create_table, link_to_local);
 
1552
        create_table->create= true;
 
1553
      }
 
1554
 
 
1555
      if (!(res= open_and_lock_tables(thd, lex->query_tables)))
 
1556
      {
 
1557
        /*
 
1558
          Is table which we are changing used somewhere in other parts
 
1559
          of query
 
1560
        */
 
1561
        if (!(create_info.options & HA_LEX_CREATE_TMP_TABLE))
 
1562
        {
 
1563
          TABLE_LIST *duplicate;
 
1564
          create_table= lex->unlink_first_table(&link_to_local);
 
1565
          if ((duplicate= unique_table(thd, create_table, select_tables, 0)))
 
1566
          {
 
1567
            update_non_unique_table_error(create_table, "CREATE", duplicate);
 
1568
            res= 1;
 
1569
            goto end_with_restore_list;
 
1570
          }
 
1571
        }
 
1572
        /* If we create merge table, we have to test tables in merge, too */
 
1573
        if (create_info.used_fields & HA_CREATE_USED_UNION)
 
1574
        {
 
1575
          TABLE_LIST *tab;
 
1576
          for (tab= (TABLE_LIST*) create_info.merge_list.first;
 
1577
               tab;
 
1578
               tab= tab->next_local)
 
1579
          {
 
1580
            TABLE_LIST *duplicate;
 
1581
            if ((duplicate= unique_table(thd, tab, select_tables, 0)))
 
1582
            {
 
1583
              update_non_unique_table_error(tab, "CREATE", duplicate);
 
1584
              res= 1;
 
1585
              goto end_with_restore_list;
 
1586
            }
 
1587
          }
 
1588
        }
 
1589
 
 
1590
        /*
 
1591
          select_create is currently not re-execution friendly and
 
1592
          needs to be created for every execution of a PS/SP.
 
1593
        */
 
1594
        if ((result= new select_create(create_table,
 
1595
                                       &create_info,
 
1596
                                       &alter_info,
 
1597
                                       select_lex->item_list,
 
1598
                                       lex->duplicates,
 
1599
                                       lex->ignore,
 
1600
                                       select_tables)))
 
1601
        {
 
1602
          /*
 
1603
            CREATE from SELECT give its SELECT_LEX for SELECT,
 
1604
            and item_list belong to SELECT
 
1605
          */
 
1606
          res= handle_select(thd, lex, result, 0);
 
1607
          delete result;
 
1608
        }
 
1609
      }
 
1610
      else if (!(create_info.options & HA_LEX_CREATE_TMP_TABLE))
 
1611
        create_table= lex->unlink_first_table(&link_to_local);
 
1612
 
 
1613
    }
 
1614
    else
 
1615
    {
 
1616
      /* So that CREATE TEMPORARY TABLE gets to binlog at commit/rollback */
 
1617
      if (create_info.options & HA_LEX_CREATE_TMP_TABLE)
 
1618
        thd->options|= OPTION_KEEP_LOG;
 
1619
      /* regular create */
 
1620
      if (create_info.options & HA_LEX_CREATE_TABLE_LIKE)
 
1621
        res= mysql_create_like_table(thd, create_table, select_tables,
 
1622
                                     &create_info);
 
1623
      else
 
1624
      {
 
1625
        res= mysql_create_table(thd, create_table->db,
 
1626
                                create_table->table_name, &create_info,
 
1627
                                &alter_info, 0, 0);
 
1628
      }
 
1629
      if (!res)
 
1630
        my_ok(thd);
 
1631
    }
 
1632
 
 
1633
    /* put tables back for PS rexecuting */
 
1634
end_with_restore_list:
 
1635
    lex->link_first_table_back(create_table, link_to_local);
 
1636
    break;
 
1637
  }
 
1638
  case SQLCOM_CREATE_INDEX:
 
1639
    /* Fall through */
 
1640
  case SQLCOM_DROP_INDEX:
 
1641
  /*
 
1642
    CREATE INDEX and DROP INDEX are implemented by calling ALTER
 
1643
    TABLE with proper arguments.
 
1644
 
 
1645
    In the future ALTER TABLE will notice that the request is to
 
1646
    only add indexes and create these one by one for the existing
 
1647
    table without having to do a full rebuild.
 
1648
  */
 
1649
  {
 
1650
    /* Prepare stack copies to be re-execution safe */
 
1651
    HA_CREATE_INFO create_info;
 
1652
    Alter_info alter_info(lex->alter_info, thd->mem_root);
 
1653
 
 
1654
    if (thd->is_fatal_error) /* out of memory creating a copy of alter_info */
 
1655
      goto error;
 
1656
 
 
1657
    assert(first_table == all_tables && first_table != 0);
 
1658
    if (end_active_trans(thd))
 
1659
      goto error;
 
1660
    /*
 
1661
      Currently CREATE INDEX or DROP INDEX cause a full table rebuild
 
1662
      and thus classify as slow administrative statements just like
 
1663
      ALTER TABLE.
 
1664
    */
 
1665
    thd->enable_slow_log= opt_log_slow_admin_statements;
 
1666
 
 
1667
    bzero((char*) &create_info, sizeof(create_info));
 
1668
    create_info.db_type= 0;
 
1669
    create_info.row_type= ROW_TYPE_NOT_USED;
 
1670
    create_info.default_table_charset= thd->variables.collation_database;
 
1671
 
 
1672
    res= mysql_alter_table(thd, first_table->db, first_table->table_name,
 
1673
                           &create_info, first_table, &alter_info,
 
1674
                           0, (ORDER*) 0, 0);
 
1675
    break;
 
1676
  }
 
1677
#ifdef HAVE_REPLICATION
 
1678
  case SQLCOM_SLAVE_START:
 
1679
  {
 
1680
    pthread_mutex_lock(&LOCK_active_mi);
 
1681
    start_slave(thd,active_mi,1 /* net report*/);
 
1682
    pthread_mutex_unlock(&LOCK_active_mi);
 
1683
    break;
 
1684
  }
 
1685
  case SQLCOM_SLAVE_STOP:
 
1686
  /*
 
1687
    If the client thread has locked tables, a deadlock is possible.
 
1688
    Assume that
 
1689
    - the client thread does LOCK TABLE t READ.
 
1690
    - then the master updates t.
 
1691
    - then the SQL slave thread wants to update t,
 
1692
      so it waits for the client thread because t is locked by it.
 
1693
    - then the client thread does SLAVE STOP.
 
1694
      SLAVE STOP waits for the SQL slave thread to terminate its
 
1695
      update t, which waits for the client thread because t is locked by it.
 
1696
    To prevent that, refuse SLAVE STOP if the
 
1697
    client thread has locked tables
 
1698
  */
 
1699
  if (thd->locked_tables || thd->active_transaction() || thd->global_read_lock)
 
1700
  {
 
1701
    my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
 
1702
               ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
 
1703
    goto error;
 
1704
  }
 
1705
  {
 
1706
    pthread_mutex_lock(&LOCK_active_mi);
 
1707
    stop_slave(thd,active_mi,1/* net report*/);
 
1708
    pthread_mutex_unlock(&LOCK_active_mi);
 
1709
    break;
 
1710
  }
 
1711
#endif /* HAVE_REPLICATION */
 
1712
 
 
1713
  case SQLCOM_ALTER_TABLE:
 
1714
    assert(first_table == all_tables && first_table != 0);
 
1715
    {
 
1716
      /*
 
1717
        Code in mysql_alter_table() may modify its HA_CREATE_INFO argument,
 
1718
        so we have to use a copy of this structure to make execution
 
1719
        prepared statement- safe. A shallow copy is enough as no memory
 
1720
        referenced from this structure will be modified.
 
1721
      */
 
1722
      HA_CREATE_INFO create_info(lex->create_info);
 
1723
      Alter_info alter_info(lex->alter_info, thd->mem_root);
 
1724
 
 
1725
      if (thd->is_fatal_error) /* out of memory creating a copy of alter_info */
 
1726
      {
 
1727
        goto error;
 
1728
      }
 
1729
 
 
1730
      /* Must be set in the parser */
 
1731
      assert(select_lex->db);
 
1732
 
 
1733
      { // Rename of table
 
1734
          TABLE_LIST tmp_table;
 
1735
          bzero((char*) &tmp_table,sizeof(tmp_table));
 
1736
          tmp_table.table_name= lex->name.str;
 
1737
          tmp_table.db=select_lex->db;
 
1738
      }
 
1739
 
 
1740
      /* Don't yet allow changing of symlinks with ALTER TABLE */
 
1741
      if (create_info.data_file_name)
 
1742
        push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, 0,
 
1743
                     "DATA DIRECTORY option ignored");
 
1744
      if (create_info.index_file_name)
 
1745
        push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, 0,
 
1746
                     "INDEX DIRECTORY option ignored");
 
1747
      create_info.data_file_name= create_info.index_file_name= NULL;
 
1748
      /* ALTER TABLE ends previous transaction */
 
1749
      if (end_active_trans(thd))
 
1750
        goto error;
 
1751
 
 
1752
      if (!thd->locked_tables &&
 
1753
          !(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
 
1754
      {
 
1755
        res= 1;
 
1756
        break;
 
1757
      }
 
1758
 
 
1759
      thd->enable_slow_log= opt_log_slow_admin_statements;
 
1760
      res= mysql_alter_table(thd, select_lex->db, lex->name.str,
 
1761
                             &create_info,
 
1762
                             first_table,
 
1763
                             &alter_info,
 
1764
                             select_lex->order_list.elements,
 
1765
                             (ORDER *) select_lex->order_list.first,
 
1766
                             lex->ignore);
 
1767
      break;
 
1768
    }
 
1769
  case SQLCOM_RENAME_TABLE:
 
1770
  {
 
1771
    assert(first_table == all_tables && first_table != 0);
 
1772
    TABLE_LIST *table;
 
1773
    for (table= first_table; table; table= table->next_local->next_local)
 
1774
    {
 
1775
      TABLE_LIST old_list, new_list;
 
1776
      /*
 
1777
        we do not need initialize old_list and new_list because we will
 
1778
        come table[0] and table->next[0] there
 
1779
      */
 
1780
      old_list= table[0];
 
1781
      new_list= table->next_local[0];
 
1782
    }
 
1783
 
 
1784
    if (end_active_trans(thd) || mysql_rename_tables(thd, first_table, 0))
 
1785
      {
 
1786
        goto error;
 
1787
      }
 
1788
    break;
 
1789
  }
 
1790
  case SQLCOM_SHOW_BINLOGS:
 
1791
    {
 
1792
      res = show_binlogs(thd);
 
1793
      break;
 
1794
    }
 
1795
  case SQLCOM_SHOW_CREATE:
 
1796
    assert(first_table == all_tables && first_table != 0);
 
1797
    {
 
1798
      res= mysqld_show_create(thd, first_table);
 
1799
      break;
 
1800
    }
 
1801
  case SQLCOM_CHECKSUM:
 
1802
  {
 
1803
    assert(first_table == all_tables && first_table != 0);
 
1804
    res = mysql_checksum_table(thd, first_table, &lex->check_opt);
 
1805
    break;
 
1806
  }
 
1807
  case SQLCOM_REPAIR:
 
1808
  {
 
1809
    assert(first_table == all_tables && first_table != 0);
 
1810
    thd->enable_slow_log= opt_log_slow_admin_statements;
 
1811
    res= mysql_repair_table(thd, first_table, &lex->check_opt);
 
1812
    /* ! we write after unlocking the table */
 
1813
    if (!res && !lex->no_write_to_binlog)
 
1814
    {
 
1815
      /*
 
1816
        Presumably, REPAIR and binlog writing doesn't require synchronization
 
1817
      */
 
1818
      write_bin_log(thd, true, thd->query, thd->query_length);
 
1819
    }
 
1820
    select_lex->table_list.first= (uchar*) first_table;
 
1821
    lex->query_tables=all_tables;
 
1822
    break;
 
1823
  }
 
1824
  case SQLCOM_CHECK:
 
1825
  {
 
1826
    assert(first_table == all_tables && first_table != 0);
 
1827
    thd->enable_slow_log= opt_log_slow_admin_statements;
 
1828
    res = mysql_check_table(thd, first_table, &lex->check_opt);
 
1829
    select_lex->table_list.first= (uchar*) first_table;
 
1830
    lex->query_tables=all_tables;
 
1831
    break;
 
1832
  }
 
1833
  case SQLCOM_ANALYZE:
 
1834
  {
 
1835
    assert(first_table == all_tables && first_table != 0);
 
1836
    thd->enable_slow_log= opt_log_slow_admin_statements;
 
1837
    res= mysql_analyze_table(thd, first_table, &lex->check_opt);
 
1838
    /* ! we write after unlocking the table */
 
1839
    if (!res && !lex->no_write_to_binlog)
 
1840
    {
 
1841
      /*
 
1842
        Presumably, ANALYZE and binlog writing doesn't require synchronization
 
1843
      */
 
1844
      write_bin_log(thd, true, thd->query, thd->query_length);
 
1845
    }
 
1846
    select_lex->table_list.first= (uchar*) first_table;
 
1847
    lex->query_tables=all_tables;
 
1848
    break;
 
1849
  }
 
1850
 
 
1851
  case SQLCOM_OPTIMIZE:
 
1852
  {
 
1853
    assert(first_table == all_tables && first_table != 0);
 
1854
    thd->enable_slow_log= opt_log_slow_admin_statements;
 
1855
    res= (specialflag & (SPECIAL_SAFE_MODE | SPECIAL_NO_NEW_FUNC)) ?
 
1856
      mysql_recreate_table(thd, first_table) :
 
1857
      mysql_optimize_table(thd, first_table, &lex->check_opt);
 
1858
    /* ! we write after unlocking the table */
 
1859
    if (!res && !lex->no_write_to_binlog)
 
1860
    {
 
1861
      /*
 
1862
        Presumably, OPTIMIZE and binlog writing doesn't require synchronization
 
1863
      */
 
1864
      write_bin_log(thd, true, thd->query, thd->query_length);
 
1865
    }
 
1866
    select_lex->table_list.first= (uchar*) first_table;
 
1867
    lex->query_tables=all_tables;
 
1868
    break;
 
1869
  }
 
1870
  case SQLCOM_UPDATE:
 
1871
    assert(first_table == all_tables && first_table != 0);
 
1872
    if (update_precheck(thd, all_tables))
 
1873
      break;
 
1874
    assert(select_lex->offset_limit == 0);
 
1875
    unit->set_limit(select_lex);
 
1876
    res= (up_result= mysql_update(thd, all_tables,
 
1877
                                  select_lex->item_list,
 
1878
                                  lex->value_list,
 
1879
                                  select_lex->where,
 
1880
                                  select_lex->order_list.elements,
 
1881
                                  (ORDER *) select_lex->order_list.first,
 
1882
                                  unit->select_limit_cnt,
 
1883
                                  lex->duplicates, lex->ignore));
 
1884
    /* mysql_update return 2 if we need to switch to multi-update */
 
1885
    if (up_result != 2)
 
1886
      break;
 
1887
    /* Fall through */
 
1888
  case SQLCOM_UPDATE_MULTI:
 
1889
  {
 
1890
    assert(first_table == all_tables && first_table != 0);
 
1891
    /* if we switched from normal update, rights are checked */
 
1892
    if (up_result != 2)
 
1893
    {
 
1894
      if ((res= multi_update_precheck(thd, all_tables)))
 
1895
        break;
 
1896
    }
 
1897
    else
 
1898
      res= 0;
 
1899
 
 
1900
    res= mysql_multi_update_prepare(thd);
 
1901
 
 
1902
#ifdef HAVE_REPLICATION
 
1903
    /* Check slave filtering rules */
 
1904
    if (unlikely(thd->slave_thread))
 
1905
    {
 
1906
      if (all_tables_not_ok(thd, all_tables))
 
1907
      {
 
1908
        if (res!= 0)
 
1909
        {
 
1910
          res= 0;             /* don't care of prev failure  */
 
1911
          thd->clear_error(); /* filters are of highest prior */
 
1912
        }
 
1913
        /* we warn the slave SQL thread */
 
1914
        my_error(ER_SLAVE_IGNORED_TABLE, MYF(0));
 
1915
        break;
 
1916
      }
 
1917
      if (res)
 
1918
        break;
 
1919
    }
 
1920
    else
 
1921
    {
 
1922
#endif /* HAVE_REPLICATION */
 
1923
      if (res)
 
1924
        break;
 
1925
      if (opt_readonly &&
 
1926
          some_non_temp_table_to_be_updated(thd, all_tables))
 
1927
      {
 
1928
        my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--read-only");
 
1929
        break;
 
1930
      }
 
1931
#ifdef HAVE_REPLICATION
 
1932
    }  /* unlikely */
 
1933
#endif
 
1934
 
 
1935
    res= mysql_multi_update(thd, all_tables,
 
1936
                            &select_lex->item_list,
 
1937
                            &lex->value_list,
 
1938
                            select_lex->where,
 
1939
                            select_lex->options,
 
1940
                            lex->duplicates, lex->ignore, unit, select_lex);
 
1941
    break;
 
1942
  }
 
1943
  case SQLCOM_REPLACE:
 
1944
  case SQLCOM_INSERT:
 
1945
  {
 
1946
    assert(first_table == all_tables && first_table != 0);
 
1947
    if ((res= insert_precheck(thd, all_tables)))
 
1948
      break;
 
1949
 
 
1950
    if (!thd->locked_tables &&
 
1951
        !(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
 
1952
    {
 
1953
      res= 1;
 
1954
      break;
 
1955
    }
 
1956
 
 
1957
    res= mysql_insert(thd, all_tables, lex->field_list, lex->many_values,
 
1958
                      lex->update_list, lex->value_list,
 
1959
                      lex->duplicates, lex->ignore);
 
1960
 
 
1961
    break;
 
1962
  }
 
1963
  case SQLCOM_REPLACE_SELECT:
 
1964
  case SQLCOM_INSERT_SELECT:
 
1965
  {
 
1966
    select_result *sel_result;
 
1967
    assert(first_table == all_tables && first_table != 0);
 
1968
    if ((res= insert_precheck(thd, all_tables)))
 
1969
      break;
 
1970
 
 
1971
    /* Fix lock for first table */
 
1972
    if (first_table->lock_type == TL_WRITE_DELAYED)
 
1973
      first_table->lock_type= TL_WRITE;
 
1974
 
 
1975
    /* Don't unlock tables until command is written to binary log */
 
1976
    select_lex->options|= SELECT_NO_UNLOCK;
 
1977
 
 
1978
    unit->set_limit(select_lex);
 
1979
 
 
1980
    if (! thd->locked_tables &&
 
1981
        ! (need_start_waiting= ! wait_if_global_read_lock(thd, 0, 1)))
 
1982
    {
 
1983
      res= 1;
 
1984
      break;
 
1985
    }
 
1986
 
 
1987
    if (!(res= open_and_lock_tables(thd, all_tables)))
 
1988
    {
 
1989
      /* Skip first table, which is the table we are inserting in */
 
1990
      TABLE_LIST *second_table= first_table->next_local;
 
1991
      select_lex->table_list.first= (uchar*) second_table;
 
1992
      select_lex->context.table_list= 
 
1993
        select_lex->context.first_name_resolution_table= second_table;
 
1994
      res= mysql_insert_select_prepare(thd);
 
1995
      if (!res && (sel_result= new select_insert(first_table,
 
1996
                                                 first_table->table,
 
1997
                                                 &lex->field_list,
 
1998
                                                 &lex->update_list,
 
1999
                                                 &lex->value_list,
 
2000
                                                 lex->duplicates,
 
2001
                                                 lex->ignore)))
 
2002
      {
 
2003
        res= handle_select(thd, lex, sel_result, OPTION_SETUP_TABLES_DONE);
 
2004
        /*
 
2005
          Invalidate the table in the query cache if something changed
 
2006
          after unlocking when changes become visible.
 
2007
          TODO: this is workaround. right way will be move invalidating in
 
2008
          the unlock procedure.
 
2009
        */
 
2010
        if (first_table->lock_type ==  TL_WRITE_CONCURRENT_INSERT &&
 
2011
            thd->lock)
 
2012
        {
 
2013
          /* INSERT ... SELECT should invalidate only the very first table */
 
2014
          TABLE_LIST *save_table= first_table->next_local;
 
2015
          first_table->next_local= 0;
 
2016
          first_table->next_local= save_table;
 
2017
        }
 
2018
        delete sel_result;
 
2019
      }
 
2020
      /* revert changes for SP */
 
2021
      select_lex->table_list.first= (uchar*) first_table;
 
2022
    }
 
2023
 
 
2024
    break;
 
2025
  }
 
2026
  case SQLCOM_TRUNCATE:
 
2027
    if (end_active_trans(thd))
 
2028
    {
 
2029
      res= -1;
 
2030
      break;
 
2031
    }
 
2032
    assert(first_table == all_tables && first_table != 0);
 
2033
    /*
 
2034
      Don't allow this within a transaction because we want to use
 
2035
      re-generate table
 
2036
    */
 
2037
    if (thd->locked_tables || thd->active_transaction())
 
2038
    {
 
2039
      my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
 
2040
                 ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
 
2041
      goto error;
 
2042
    }
 
2043
 
 
2044
    res= mysql_truncate(thd, first_table, 0);
 
2045
 
 
2046
    break;
 
2047
  case SQLCOM_DELETE:
 
2048
  {
 
2049
    assert(first_table == all_tables && first_table != 0);
 
2050
    assert(select_lex->offset_limit == 0);
 
2051
    unit->set_limit(select_lex);
 
2052
 
 
2053
    if (!thd->locked_tables &&
 
2054
        !(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
 
2055
    {
 
2056
      res= 1;
 
2057
      break;
 
2058
    }
 
2059
 
 
2060
    res = mysql_delete(thd, all_tables, select_lex->where,
 
2061
                       &select_lex->order_list,
 
2062
                       unit->select_limit_cnt, select_lex->options,
 
2063
                       false);
 
2064
    break;
 
2065
  }
 
2066
  case SQLCOM_DELETE_MULTI:
 
2067
  {
 
2068
    assert(first_table == all_tables && first_table != 0);
 
2069
    TABLE_LIST *aux_tables=
 
2070
      (TABLE_LIST *)thd->lex->auxiliary_table_list.first;
 
2071
    multi_delete *del_result;
 
2072
 
 
2073
    if (!thd->locked_tables &&
 
2074
        !(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
 
2075
    {
 
2076
      res= 1;
 
2077
      break;
 
2078
    }
 
2079
 
 
2080
    if ((res= multi_delete_precheck(thd, all_tables)))
 
2081
      break;
 
2082
 
 
2083
    /* condition will be true on SP re-excuting */
 
2084
    if (select_lex->item_list.elements != 0)
 
2085
      select_lex->item_list.empty();
 
2086
    if (add_item_to_list(thd, new Item_null()))
 
2087
      goto error;
 
2088
 
 
2089
    thd_proc_info(thd, "init");
 
2090
    if ((res= open_and_lock_tables(thd, all_tables)))
 
2091
      break;
 
2092
 
 
2093
    if ((res= mysql_multi_delete_prepare(thd)))
 
2094
      goto error;
 
2095
 
 
2096
    if (!thd->is_fatal_error &&
 
2097
        (del_result= new multi_delete(aux_tables, lex->table_count)))
 
2098
    {
 
2099
      res= mysql_select(thd, &select_lex->ref_pointer_array,
 
2100
                        select_lex->get_table_list(),
 
2101
                        select_lex->with_wild,
 
2102
                        select_lex->item_list,
 
2103
                        select_lex->where,
 
2104
                        0, (ORDER *)NULL, (ORDER *)NULL, (Item *)NULL,
 
2105
                        (ORDER *)NULL,
 
2106
                        select_lex->options | thd->options |
 
2107
                        SELECT_NO_JOIN_CACHE | SELECT_NO_UNLOCK |
 
2108
                        OPTION_SETUP_TABLES_DONE,
 
2109
                        del_result, unit, select_lex);
 
2110
      res|= thd->is_error();
 
2111
      if (res)
 
2112
        del_result->abort();
 
2113
      delete del_result;
 
2114
    }
 
2115
    else
 
2116
      res= true;                                // Error
 
2117
    break;
 
2118
  }
 
2119
  case SQLCOM_DROP_TABLE:
 
2120
  {
 
2121
    assert(first_table == all_tables && first_table != 0);
 
2122
    if (!lex->drop_temporary)
 
2123
    {
 
2124
      if (end_active_trans(thd))
 
2125
        goto error;
 
2126
    }
 
2127
    else
 
2128
    {
 
2129
      /*
 
2130
        If this is a slave thread, we may sometimes execute some 
 
2131
        DROP / * 40005 TEMPORARY * / TABLE
 
2132
        that come from parts of binlogs (likely if we use RESET SLAVE or CHANGE
 
2133
        MASTER TO), while the temporary table has already been dropped.
 
2134
        To not generate such irrelevant "table does not exist errors",
 
2135
        we silently add IF EXISTS if TEMPORARY was used.
 
2136
      */
 
2137
      if (thd->slave_thread)
 
2138
        lex->drop_if_exists= 1;
 
2139
 
 
2140
      /* So that DROP TEMPORARY TABLE gets to binlog at commit/rollback */
 
2141
      thd->options|= OPTION_KEEP_LOG;
 
2142
    }
 
2143
    /* DDL and binlog write order protected by LOCK_open */
 
2144
    res= mysql_rm_table(thd, first_table, lex->drop_if_exists,
 
2145
                        lex->drop_temporary);
 
2146
  }
 
2147
  break;
 
2148
  case SQLCOM_SHOW_PROCESSLIST:
 
2149
    mysqld_list_processes(thd, NullS, lex->verbose);
 
2150
    break;
 
2151
  case SQLCOM_SHOW_ENGINE_LOGS:
 
2152
    {
 
2153
      res= ha_show_status(thd, lex->create_info.db_type, HA_ENGINE_LOGS);
 
2154
      break;
 
2155
    }
 
2156
  case SQLCOM_CHANGE_DB:
 
2157
  {
 
2158
    LEX_STRING db_str= { (char *) select_lex->db, strlen(select_lex->db) };
 
2159
 
 
2160
    if (!mysql_change_db(thd, &db_str, false))
 
2161
      my_ok(thd);
 
2162
 
 
2163
    break;
 
2164
  }
 
2165
 
 
2166
  case SQLCOM_LOAD:
 
2167
  {
 
2168
    assert(first_table == all_tables && first_table != 0);
 
2169
    if (lex->local_file)
 
2170
    {
 
2171
      if (!(thd->client_capabilities & CLIENT_LOCAL_FILES) ||
 
2172
          !opt_local_infile)
 
2173
      {
 
2174
        my_message(ER_NOT_ALLOWED_COMMAND, ER(ER_NOT_ALLOWED_COMMAND), MYF(0));
 
2175
        goto error;
 
2176
      }
 
2177
    }
 
2178
 
 
2179
    res= mysql_load(thd, lex->exchange, first_table, lex->field_list,
 
2180
                    lex->update_list, lex->value_list, lex->duplicates,
 
2181
                    lex->ignore, (bool) lex->local_file);
 
2182
    break;
 
2183
  }
 
2184
 
 
2185
  case SQLCOM_SET_OPTION:
 
2186
  {
 
2187
    List<set_var_base> *lex_var_list= &lex->var_list;
 
2188
 
 
2189
    if (lex->autocommit && end_active_trans(thd))
 
2190
      goto error;
 
2191
 
 
2192
    if (open_and_lock_tables(thd, all_tables))
 
2193
      goto error;
 
2194
    if (lex->one_shot_set && not_all_support_one_shot(lex_var_list))
 
2195
    {
 
2196
      my_error(ER_RESERVED_SYNTAX, MYF(0), "SET ONE_SHOT");
 
2197
      goto error;
 
2198
    }
 
2199
    if (!(res= sql_set_variables(thd, lex_var_list)))
 
2200
    {
 
2201
      /*
 
2202
        If the previous command was a SET ONE_SHOT, we don't want to forget
 
2203
        about the ONE_SHOT property of that SET. So we use a |= instead of = .
 
2204
      */
 
2205
      thd->one_shot_set|= lex->one_shot_set;
 
2206
      my_ok(thd);
 
2207
    }
 
2208
    else
 
2209
    {
 
2210
      /*
 
2211
        We encountered some sort of error, but no message was sent.
 
2212
        Send something semi-generic here since we don't know which
 
2213
        assignment in the list caused the error.
 
2214
      */
 
2215
      if (!thd->is_error())
 
2216
        my_error(ER_WRONG_ARGUMENTS,MYF(0),"SET");
 
2217
      goto error;
 
2218
    }
 
2219
 
 
2220
    break;
 
2221
  }
 
2222
 
 
2223
  case SQLCOM_UNLOCK_TABLES:
 
2224
    /*
 
2225
      It is critical for mysqldump --single-transaction --master-data that
 
2226
      UNLOCK TABLES does not implicitely commit a connection which has only
 
2227
      done FLUSH TABLES WITH READ LOCK + BEGIN. If this assumption becomes
 
2228
      false, mysqldump will not work.
 
2229
    */
 
2230
    unlock_locked_tables(thd);
 
2231
    if (thd->options & OPTION_TABLE_LOCK)
 
2232
    {
 
2233
      end_active_trans(thd);
 
2234
      thd->options&= ~(OPTION_TABLE_LOCK);
 
2235
    }
 
2236
    if (thd->global_read_lock)
 
2237
      unlock_global_read_lock(thd);
 
2238
    my_ok(thd);
 
2239
    break;
 
2240
  case SQLCOM_LOCK_TABLES:
 
2241
    /*
 
2242
      We try to take transactional locks if
 
2243
      - only transactional locks are requested (lex->lock_transactional) and
 
2244
      - no non-transactional locks exist (!thd->locked_tables).
 
2245
    */
 
2246
    if (lex->lock_transactional && !thd->locked_tables)
 
2247
    {
 
2248
      int rc;
 
2249
      /*
 
2250
        All requested locks are transactional and no non-transactional
 
2251
        locks exist.
 
2252
      */
 
2253
      if ((rc= try_transactional_lock(thd, all_tables)) == -1)
 
2254
        goto error;
 
2255
      if (rc == 0)
 
2256
      {
 
2257
        my_ok(thd);
 
2258
        break;
 
2259
      }
 
2260
      /*
 
2261
        Non-transactional locking has been requested or
 
2262
        non-transactional locks exist already or transactional locks are
 
2263
        not supported by all storage engines. Take non-transactional
 
2264
        locks.
 
2265
      */
 
2266
    }
 
2267
    /*
 
2268
      One or more requested locks are non-transactional and/or
 
2269
      non-transactional locks exist or a storage engine does not support
 
2270
      transactional locks. Check if at least one transactional lock is
 
2271
      requested. If yes, warn about the conversion to non-transactional
 
2272
      locks or abort in strict mode.
 
2273
    */
 
2274
    if (check_transactional_lock(thd, all_tables))
 
2275
      goto error;
 
2276
    unlock_locked_tables(thd);
 
2277
    /* we must end the trasaction first, regardless of anything */
 
2278
    if (end_active_trans(thd))
 
2279
      goto error;
 
2280
    thd->in_lock_tables=1;
 
2281
    thd->options|= OPTION_TABLE_LOCK;
 
2282
 
 
2283
    if (!(res= simple_open_n_lock_tables(thd, all_tables)))
 
2284
    {
 
2285
      thd->locked_tables=thd->lock;
 
2286
      thd->lock=0;
 
2287
      (void) set_handler_table_locks(thd, all_tables, false);
 
2288
      my_ok(thd);
 
2289
    }
 
2290
    else
 
2291
    {
 
2292
      /* 
 
2293
        Need to end the current transaction, so the storage engine (InnoDB)
 
2294
        can free its locks if LOCK TABLES locked some tables before finding
 
2295
        that it can't lock a table in its list
 
2296
      */
 
2297
      ha_autocommit_or_rollback(thd, 1);
 
2298
      end_active_trans(thd);
 
2299
      thd->options&= ~(OPTION_TABLE_LOCK);
 
2300
    }
 
2301
    thd->in_lock_tables=0;
 
2302
    break;
 
2303
  case SQLCOM_CREATE_DB:
 
2304
  {
 
2305
    /*
 
2306
      As mysql_create_db() may modify HA_CREATE_INFO structure passed to
 
2307
      it, we need to use a copy of LEX::create_info to make execution
 
2308
      prepared statement- safe.
 
2309
    */
 
2310
    HA_CREATE_INFO create_info(lex->create_info);
 
2311
    if (end_active_trans(thd))
 
2312
    {
 
2313
      res= -1;
 
2314
      break;
 
2315
    }
 
2316
    char *alias;
 
2317
    if (!(alias=thd->strmake(lex->name.str, lex->name.length)) ||
 
2318
        check_db_name(&lex->name))
 
2319
    {
 
2320
      my_error(ER_WRONG_DB_NAME, MYF(0), lex->name.str);
 
2321
      break;
 
2322
    }
 
2323
    /*
 
2324
      If in a slave thread :
 
2325
      CREATE DATABASE DB was certainly not preceded by USE DB.
 
2326
      For that reason, db_ok() in sql/slave.cc did not check the
 
2327
      do_db/ignore_db. And as this query involves no tables, tables_ok()
 
2328
      above was not called. So we have to check rules again here.
 
2329
    */
 
2330
    if (thd->slave_thread && 
 
2331
        (!rpl_filter->db_ok(lex->name.str) ||
 
2332
         !rpl_filter->db_ok_with_wild_table(lex->name.str)))
 
2333
    {
 
2334
      my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0));
 
2335
      break;
 
2336
    }
 
2337
    res= mysql_create_db(thd,(lower_case_table_names == 2 ? alias :
 
2338
                              lex->name.str), &create_info, 0);
 
2339
    break;
 
2340
  }
 
2341
  case SQLCOM_DROP_DB:
 
2342
  {
 
2343
    if (end_active_trans(thd))
 
2344
    {
 
2345
      res= -1;
 
2346
      break;
 
2347
    }
 
2348
    if (check_db_name(&lex->name))
 
2349
    {
 
2350
      my_error(ER_WRONG_DB_NAME, MYF(0), lex->name.str);
 
2351
      break;
 
2352
    }
 
2353
    /*
 
2354
      If in a slave thread :
 
2355
      DROP DATABASE DB may not be preceded by USE DB.
 
2356
      For that reason, maybe db_ok() in sql/slave.cc did not check the 
 
2357
      do_db/ignore_db. And as this query involves no tables, tables_ok()
 
2358
      above was not called. So we have to check rules again here.
 
2359
    */
 
2360
#ifdef HAVE_REPLICATION
 
2361
    if (thd->slave_thread && 
 
2362
        (!rpl_filter->db_ok(lex->name.str) ||
 
2363
         !rpl_filter->db_ok_with_wild_table(lex->name.str)))
 
2364
    {
 
2365
      my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0));
 
2366
      break;
 
2367
    }
 
2368
#endif
 
2369
    if (thd->locked_tables || thd->active_transaction())
 
2370
    {
 
2371
      my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
 
2372
                 ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
 
2373
      goto error;
 
2374
    }
 
2375
    res= mysql_rm_db(thd, lex->name.str, lex->drop_if_exists, 0);
 
2376
    break;
 
2377
  }
 
2378
  case SQLCOM_ALTER_DB_UPGRADE:
 
2379
  {
 
2380
    LEX_STRING *db= & lex->name;
 
2381
    if (end_active_trans(thd))
 
2382
    {
 
2383
      res= 1;
 
2384
      break;
 
2385
    }
 
2386
#ifdef HAVE_REPLICATION
 
2387
    if (thd->slave_thread && 
 
2388
       (!rpl_filter->db_ok(db->str) ||
 
2389
        !rpl_filter->db_ok_with_wild_table(db->str)))
 
2390
    {
 
2391
      res= 1;
 
2392
      my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0));
 
2393
      break;
 
2394
    }
 
2395
#endif
 
2396
    if (check_db_name(db))
 
2397
    {
 
2398
      my_error(ER_WRONG_DB_NAME, MYF(0), db->str);
 
2399
      break;
 
2400
    }
 
2401
    if (thd->locked_tables || thd->active_transaction())
 
2402
    {
 
2403
      res= 1;
 
2404
      my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
 
2405
                 ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
 
2406
      goto error;
 
2407
    }
 
2408
 
 
2409
    res= mysql_upgrade_db(thd, db);
 
2410
    if (!res)
 
2411
      my_ok(thd);
 
2412
    break;
 
2413
  }
 
2414
  case SQLCOM_ALTER_DB:
 
2415
  {
 
2416
    LEX_STRING *db= &lex->name;
 
2417
    HA_CREATE_INFO create_info(lex->create_info);
 
2418
    if (check_db_name(db))
 
2419
    {
 
2420
      my_error(ER_WRONG_DB_NAME, MYF(0), db->str);
 
2421
      break;
 
2422
    }
 
2423
    /*
 
2424
      If in a slave thread :
 
2425
      ALTER DATABASE DB may not be preceded by USE DB.
 
2426
      For that reason, maybe db_ok() in sql/slave.cc did not check the
 
2427
      do_db/ignore_db. And as this query involves no tables, tables_ok()
 
2428
      above was not called. So we have to check rules again here.
 
2429
    */
 
2430
#ifdef HAVE_REPLICATION
 
2431
    if (thd->slave_thread &&
 
2432
        (!rpl_filter->db_ok(db->str) ||
 
2433
         !rpl_filter->db_ok_with_wild_table(db->str)))
 
2434
    {
 
2435
      my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0));
 
2436
      break;
 
2437
    }
 
2438
#endif
 
2439
    if (thd->locked_tables || thd->active_transaction())
 
2440
    {
 
2441
      my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
 
2442
                 ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
 
2443
      goto error;
 
2444
    }
 
2445
    res= mysql_alter_db(thd, db->str, &create_info);
 
2446
    break;
 
2447
  }
 
2448
  case SQLCOM_SHOW_CREATE_DB:
 
2449
  {
 
2450
    if (check_db_name(&lex->name))
 
2451
    {
 
2452
      my_error(ER_WRONG_DB_NAME, MYF(0), lex->name.str);
 
2453
      break;
 
2454
    }
 
2455
    res= mysqld_show_create_db(thd, lex->name.str, &lex->create_info);
 
2456
    break;
 
2457
  }
 
2458
  case SQLCOM_RESET:
 
2459
    /*
 
2460
      RESET commands are never written to the binary log, so we have to
 
2461
      initialize this variable because RESET shares the same code as FLUSH
 
2462
    */
 
2463
    lex->no_write_to_binlog= 1;
 
2464
  case SQLCOM_FLUSH:
 
2465
  {
 
2466
    bool write_to_binlog;
 
2467
 
 
2468
    /*
 
2469
      reload_cache() will tell us if we are allowed to write to the
 
2470
      binlog or not.
 
2471
    */
 
2472
    if (!reload_cache(thd, lex->type, first_table, &write_to_binlog))
 
2473
    {
 
2474
      /*
 
2475
        We WANT to write and we CAN write.
 
2476
        ! we write after unlocking the table.
 
2477
      */
 
2478
      /*
 
2479
        Presumably, RESET and binlog writing doesn't require synchronization
 
2480
      */
 
2481
      if (!lex->no_write_to_binlog && write_to_binlog)
 
2482
      {
 
2483
        write_bin_log(thd, false, thd->query, thd->query_length);
 
2484
      }
 
2485
      my_ok(thd);
 
2486
    } 
 
2487
    
 
2488
    break;
 
2489
  }
 
2490
  case SQLCOM_KILL:
 
2491
  {
 
2492
    Item *it= (Item *)lex->value_list.head();
 
2493
 
 
2494
    if (lex->table_or_sp_used())
 
2495
    {
 
2496
      my_error(ER_NOT_SUPPORTED_YET, MYF(0), "Usage of subqueries or stored "
 
2497
               "function calls as part of this statement");
 
2498
      break;
 
2499
    }
 
2500
 
 
2501
    if ((!it->fixed && it->fix_fields(lex->thd, &it)) || it->check_cols(1))
 
2502
    {
 
2503
      my_message(ER_SET_CONSTANTS_ONLY, ER(ER_SET_CONSTANTS_ONLY),
 
2504
                 MYF(0));
 
2505
      goto error;
 
2506
    }
 
2507
    sql_kill(thd, (ulong)it->val_int(), lex->type & ONLY_KILL_QUERY);
 
2508
    break;
 
2509
  }
 
2510
  case SQLCOM_BEGIN:
 
2511
    if (thd->transaction.xid_state.xa_state != XA_NOTR)
 
2512
    {
 
2513
      my_error(ER_XAER_RMFAIL, MYF(0),
 
2514
               xa_state_names[thd->transaction.xid_state.xa_state]);
 
2515
      break;
 
2516
    }
 
2517
    /*
 
2518
      Breakpoints for backup testing.
 
2519
    */
 
2520
    if (begin_trans(thd))
 
2521
      goto error;
 
2522
    my_ok(thd);
 
2523
    break;
 
2524
  case SQLCOM_COMMIT:
 
2525
    if (end_trans(thd, lex->tx_release ? COMMIT_RELEASE :
 
2526
                              lex->tx_chain ? COMMIT_AND_CHAIN : COMMIT))
 
2527
      goto error;
 
2528
    my_ok(thd);
 
2529
    break;
 
2530
  case SQLCOM_ROLLBACK:
 
2531
    if (end_trans(thd, lex->tx_release ? ROLLBACK_RELEASE :
 
2532
                              lex->tx_chain ? ROLLBACK_AND_CHAIN : ROLLBACK))
 
2533
      goto error;
 
2534
    my_ok(thd);
 
2535
    break;
 
2536
  case SQLCOM_RELEASE_SAVEPOINT:
 
2537
  {
 
2538
    SAVEPOINT *sv;
 
2539
    for (sv=thd->transaction.savepoints; sv; sv=sv->prev)
 
2540
    {
 
2541
      if (my_strnncoll(system_charset_info,
 
2542
                       (uchar *)lex->ident.str, lex->ident.length,
 
2543
                       (uchar *)sv->name, sv->length) == 0)
 
2544
        break;
 
2545
    }
 
2546
    if (sv)
 
2547
    {
 
2548
      if (ha_release_savepoint(thd, sv))
 
2549
        res= true; // cannot happen
 
2550
      else
 
2551
        my_ok(thd);
 
2552
      thd->transaction.savepoints=sv->prev;
 
2553
    }
 
2554
    else
 
2555
      my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "SAVEPOINT", lex->ident.str);
 
2556
    break;
 
2557
  }
 
2558
  case SQLCOM_ROLLBACK_TO_SAVEPOINT:
 
2559
  {
 
2560
    SAVEPOINT *sv;
 
2561
    for (sv=thd->transaction.savepoints; sv; sv=sv->prev)
 
2562
    {
 
2563
      if (my_strnncoll(system_charset_info,
 
2564
                       (uchar *)lex->ident.str, lex->ident.length,
 
2565
                       (uchar *)sv->name, sv->length) == 0)
 
2566
        break;
 
2567
    }
 
2568
    if (sv)
 
2569
    {
 
2570
      if (ha_rollback_to_savepoint(thd, sv))
 
2571
        res= true; // cannot happen
 
2572
      else
 
2573
      {
 
2574
        if (((thd->options & OPTION_KEEP_LOG) || 
 
2575
             thd->transaction.all.modified_non_trans_table) &&
 
2576
            !thd->slave_thread)
 
2577
          push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
 
2578
                       ER_WARNING_NOT_COMPLETE_ROLLBACK,
 
2579
                       ER(ER_WARNING_NOT_COMPLETE_ROLLBACK));
 
2580
        my_ok(thd);
 
2581
      }
 
2582
      thd->transaction.savepoints=sv;
 
2583
    }
 
2584
    else
 
2585
      my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "SAVEPOINT", lex->ident.str);
 
2586
    break;
 
2587
  }
 
2588
  case SQLCOM_SAVEPOINT:
 
2589
    if (!(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN) ||
 
2590
          thd->in_sub_stmt) || !opt_using_transactions)
 
2591
      my_ok(thd);
 
2592
    else
 
2593
    {
 
2594
      SAVEPOINT **sv, *newsv;
 
2595
      for (sv=&thd->transaction.savepoints; *sv; sv=&(*sv)->prev)
 
2596
      {
 
2597
        if (my_strnncoll(system_charset_info,
 
2598
                         (uchar *)lex->ident.str, lex->ident.length,
 
2599
                         (uchar *)(*sv)->name, (*sv)->length) == 0)
 
2600
          break;
 
2601
      }
 
2602
      if (*sv) /* old savepoint of the same name exists */
 
2603
      {
 
2604
        newsv=*sv;
 
2605
        ha_release_savepoint(thd, *sv); // it cannot fail
 
2606
        *sv=(*sv)->prev;
 
2607
      }
 
2608
      else if ((newsv=(SAVEPOINT *) alloc_root(&thd->transaction.mem_root,
 
2609
                                               savepoint_alloc_size)) == 0)
 
2610
      {
 
2611
        my_error(ER_OUT_OF_RESOURCES, MYF(0));
 
2612
        break;
 
2613
      }
 
2614
      newsv->name=strmake_root(&thd->transaction.mem_root,
 
2615
                               lex->ident.str, lex->ident.length);
 
2616
      newsv->length=lex->ident.length;
 
2617
      /*
 
2618
        if we'll get an error here, don't add new savepoint to the list.
 
2619
        we'll lose a little bit of memory in transaction mem_root, but it'll
 
2620
        be free'd when transaction ends anyway
 
2621
      */
 
2622
      if (ha_savepoint(thd, newsv))
 
2623
        res= true;
 
2624
      else
 
2625
      {
 
2626
        newsv->prev=thd->transaction.savepoints;
 
2627
        thd->transaction.savepoints=newsv;
 
2628
        my_ok(thd);
 
2629
      }
 
2630
    }
 
2631
    break;
 
2632
  case SQLCOM_BINLOG_BASE64_EVENT:
 
2633
  {
 
2634
    mysql_client_binlog_statement(thd);
 
2635
    break;
 
2636
  }
 
2637
  default:
 
2638
    assert(0);                             /* Impossible */
 
2639
    my_ok(thd);
 
2640
    break;
 
2641
  }
 
2642
  thd_proc_info(thd, "query end");
 
2643
 
 
2644
  /*
 
2645
    Binlog-related cleanup:
 
2646
    Reset system variables temporarily modified by SET ONE SHOT.
 
2647
 
 
2648
    Exception: If this is a SET, do nothing. This is to allow
 
2649
    mysqlbinlog to print many SET commands (in this case we want the
 
2650
    charset temp setting to live until the real query). This is also
 
2651
    needed so that SET CHARACTER_SET_CLIENT... does not cancel itself
 
2652
    immediately.
 
2653
  */
 
2654
  if (thd->one_shot_set && lex->sql_command != SQLCOM_SET_OPTION)
 
2655
    reset_one_shot_variables(thd);
 
2656
 
507
2657
  /*
508
2658
    The return value for ROW_COUNT() is "implementation dependent" if the
509
2659
    statement is not DELETE, INSERT or UPDATE, but -1 is what JDBC and ODBC
510
2660
    wants. We also keep the last value in case of SQLCOM_CALL or
511
2661
    SQLCOM_EXECUTE.
512
2662
  */
513
 
  if (! (sql_command_flags[session->getLex()->sql_command].test(CF_BIT_HAS_ROW_COUNT)))
 
2663
  if (!(sql_command_flags[lex->sql_command] & CF_HAS_ROW_COUNT))
 
2664
    thd->row_count_func= -1;
 
2665
 
 
2666
  goto finish;
 
2667
 
 
2668
error:
 
2669
  res= true;
 
2670
 
 
2671
finish:
 
2672
  if (need_start_waiting)
514
2673
  {
515
 
    session->row_count_func= -1;
 
2674
    /*
 
2675
      Release the protection against the global read lock and wake
 
2676
      everyone, who might want to set a global read lock.
 
2677
    */
 
2678
    start_waiting_global_read_lock(thd);
516
2679
  }
517
 
 
518
 
  return (res || session->is_error());
 
2680
  return(res || thd->is_error());
519
2681
}
520
 
bool execute_sqlcom_select(Session *session, TableList *all_tables)
 
2682
 
 
2683
 
 
2684
static bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables)
521
2685
{
522
 
  LEX   *lex= session->getLex();
 
2686
  LEX   *lex= thd->lex;
523
2687
  select_result *result=lex->result;
524
 
  bool res= false;
 
2688
  bool res;
525
2689
  /* assign global limit variable if limit is not given */
526
2690
  {
527
 
    Select_Lex *param= lex->unit.global_parameters;
 
2691
    SELECT_LEX *param= lex->unit.global_parameters;
528
2692
    if (!param->explicit_limit)
529
2693
      param->select_limit=
530
 
        new Item_int((uint64_t) session->variables.select_limit);
531
 
  }
532
 
 
533
 
  if (all_tables
534
 
      && ! (session->server_status & SERVER_STATUS_AUTOCOMMIT)
535
 
      && ! session->inTransaction()
536
 
      && ! lex->statement->isShow())
537
 
  {
538
 
    if (session->startTransaction() == false)
539
 
    {
540
 
      my_error(drizzled::ER_UNKNOWN_ERROR, MYF(0));
541
 
      return true;
542
 
    }
543
 
  }
544
 
 
545
 
  if (not (res= session->openTablesLock(all_tables)))
 
2694
        new Item_int((uint64_t) thd->variables.select_limit);
 
2695
  }
 
2696
  if (!(res= open_and_lock_tables(thd, all_tables)))
546
2697
  {
547
2698
    if (lex->describe)
548
2699
    {
553
2704
        even if the query itself redirects the output.
554
2705
      */
555
2706
      if (!(result= new select_send()))
556
 
        return true;
557
 
      session->send_explain_fields(result);
558
 
      optimizer::ExplainPlan planner;
559
 
      res= planner.explainUnion(session, &session->getLex()->unit, result);
 
2707
        return 1;                               /* purecov: inspected */
 
2708
      thd->send_explain_fields(result);
 
2709
      res= mysql_explain_union(thd, &thd->lex->unit, result);
560
2710
      if (lex->describe & DESCRIBE_EXTENDED)
561
2711
      {
562
2712
        char buff[1024];
563
 
        String str(buff,(uint32_t) sizeof(buff), system_charset_info);
 
2713
        String str(buff,(uint32) sizeof(buff), system_charset_info);
564
2714
        str.length(0);
565
 
        session->getLex()->unit.print(&str, QT_ORDINARY);
 
2715
        thd->lex->unit.print(&str, QT_ORDINARY);
566
2716
        str.append('\0');
567
 
        push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
2717
        push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
568
2718
                     ER_YES, str.ptr());
569
2719
      }
570
2720
      if (res)
571
2721
        result->abort();
572
2722
      else
573
2723
        result->send_eof();
574
 
 
575
2724
      delete result;
576
2725
    }
577
2726
    else
578
2727
    {
579
2728
      if (!result && !(result= new select_send()))
580
 
        return true;
581
 
 
582
 
      /* Init the Query Cache plugin */
583
 
      plugin::QueryCache::prepareResultset(session); 
584
 
      res= handle_select(session, lex, result, 0);
585
 
      /* Send the Resultset to the cache */
586
 
      plugin::QueryCache::setResultset(session); 
587
 
 
 
2729
        return 1;                               /* purecov: inspected */
 
2730
      res= handle_select(thd, lex, result, 0);
588
2731
      if (result != lex->result)
589
2732
        delete result;
590
2733
    }
592
2735
  return res;
593
2736
}
594
2737
 
 
2738
/****************************************************************************
 
2739
        Check stack size; Send error if there isn't enough stack to continue
 
2740
****************************************************************************/
 
2741
#if STACK_DIRECTION < 0
 
2742
#define used_stack(A,B) (long) (A - B)
 
2743
#else
 
2744
#define used_stack(A,B) (long) (B - A)
 
2745
#endif
 
2746
 
 
2747
/**
 
2748
  @note
 
2749
  Note: The 'buf' parameter is necessary, even if it is unused here.
 
2750
  - fix_fields functions has a "dummy" buffer large enough for the
 
2751
    corresponding exec. (Thus we only have to check in fix_fields.)
 
2752
  - Passing to check_stack_overrun() prevents the compiler from removing it.
 
2753
*/
 
2754
bool check_stack_overrun(THD *thd, long margin,
 
2755
                         uchar *buf __attribute__((unused)))
 
2756
{
 
2757
  long stack_used;
 
2758
  assert(thd == current_thd);
 
2759
  if ((stack_used=used_stack(thd->thread_stack,(char*) &stack_used)) >=
 
2760
      (long) (my_thread_stack_size - margin))
 
2761
  {
 
2762
    sprintf(errbuff[0],ER(ER_STACK_OVERRUN_NEED_MORE),
 
2763
            stack_used,my_thread_stack_size,margin);
 
2764
    my_message(ER_STACK_OVERRUN_NEED_MORE,errbuff[0],MYF(ME_FATALERROR));
 
2765
    return 1;
 
2766
  }
 
2767
  return 0;
 
2768
}
595
2769
 
596
2770
#define MY_YACC_INIT 1000                       // Start with big alloc
597
2771
#define MY_YACC_MAX  32000                      // Because of 'short'
598
2772
 
599
 
bool my_yyoverflow(short **yyss, ParserType **yyvs, ulong *yystacksize)
 
2773
bool my_yyoverflow(short **yyss, YYSTYPE **yyvs, ulong *yystacksize)
600
2774
{
601
 
  LEX   *lex= current_session->getLex();
 
2775
  LEX   *lex= current_thd->lex;
602
2776
  ulong old_info=0;
603
 
  if ((uint32_t) *yystacksize >= MY_YACC_MAX)
 
2777
  if ((uint) *yystacksize >= MY_YACC_MAX)
604
2778
    return 1;
605
2779
  if (!lex->yacc_yyvs)
606
2780
    old_info= *yystacksize;
607
2781
  *yystacksize= set_zone((*yystacksize)*2,MY_YACC_INIT,MY_YACC_MAX);
608
 
  unsigned char *tmpptr= NULL;
609
 
  if (!(tmpptr= (unsigned char *)realloc(lex->yacc_yyvs,
610
 
                                         *yystacksize* sizeof(**yyvs))))
611
 
      return 1;
612
 
  lex->yacc_yyvs= tmpptr;
613
 
  tmpptr= NULL;
614
 
  if (!(tmpptr= (unsigned char*)realloc(lex->yacc_yyss,
615
 
                                        *yystacksize* sizeof(**yyss))))
616
 
      return 1;
617
 
  lex->yacc_yyss= tmpptr;
 
2782
  if (!(lex->yacc_yyvs= (uchar*)
 
2783
        my_realloc(lex->yacc_yyvs,
 
2784
                   *yystacksize*sizeof(**yyvs),
 
2785
                   MYF(MY_ALLOW_ZERO_PTR | MY_FREE_ON_ERROR))) ||
 
2786
      !(lex->yacc_yyss= (uchar*)
 
2787
        my_realloc(lex->yacc_yyss,
 
2788
                   *yystacksize*sizeof(**yyss),
 
2789
                   MYF(MY_ALLOW_ZERO_PTR | MY_FREE_ON_ERROR))))
 
2790
    return 1;
618
2791
  if (old_info)
619
2792
  {                                             // Copy old info from stack
620
 
    memcpy(lex->yacc_yyss, *yyss, old_info*sizeof(**yyss));
621
 
    memcpy(lex->yacc_yyvs, *yyvs, old_info*sizeof(**yyvs));
 
2793
    memcpy(lex->yacc_yyss, (uchar*) *yyss, old_info*sizeof(**yyss));
 
2794
    memcpy(lex->yacc_yyvs, (uchar*) *yyvs, old_info*sizeof(**yyvs));
622
2795
  }
623
2796
  *yyss=(short*) lex->yacc_yyss;
624
 
  *yyvs=(ParserType*) lex->yacc_yyvs;
 
2797
  *yyvs=(YYSTYPE*) lex->yacc_yyvs;
625
2798
  return 0;
626
2799
}
627
2800
 
628
2801
 
 
2802
/**
 
2803
 Reset THD part responsible for command processing state.
 
2804
 
 
2805
   This needs to be called before execution of every statement
 
2806
   (prepared or conventional).
 
2807
   It is not called by substatements of routines.
 
2808
 
 
2809
  @todo
 
2810
   Make it a method of THD and align its name with the rest of
 
2811
   reset/end/start/init methods.
 
2812
  @todo
 
2813
   Call it after we use THD for queries, not before.
 
2814
*/
 
2815
 
 
2816
void mysql_reset_thd_for_next_command(THD *thd)
 
2817
{
 
2818
  assert(! thd->in_sub_stmt);
 
2819
  thd->free_list= 0;
 
2820
  thd->select_number= 1;
 
2821
  /*
 
2822
    Those two lines below are theoretically unneeded as
 
2823
    THD::cleanup_after_query() should take care of this already.
 
2824
  */
 
2825
  thd->auto_inc_intervals_in_cur_stmt_for_binlog.empty();
 
2826
  thd->stmt_depends_on_first_successful_insert_id_in_prev_stmt= 0;
 
2827
 
 
2828
  thd->query_start_used= 0;
 
2829
  thd->is_fatal_error= thd->time_zone_used= 0;
 
2830
  thd->server_status&= ~ (SERVER_MORE_RESULTS_EXISTS | 
 
2831
                          SERVER_QUERY_NO_INDEX_USED |
 
2832
                          SERVER_QUERY_NO_GOOD_INDEX_USED);
 
2833
  /*
 
2834
    If in autocommit mode and not in a transaction, reset
 
2835
    OPTION_STATUS_NO_TRANS_UPDATE | OPTION_KEEP_LOG to not get warnings
 
2836
    in ha_rollback_trans() about some tables couldn't be rolled back.
 
2837
  */
 
2838
  if (!(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))
 
2839
  {
 
2840
    thd->options&= ~OPTION_KEEP_LOG;
 
2841
    thd->transaction.all.modified_non_trans_table= false;
 
2842
  }
 
2843
  assert(thd->security_ctx== &thd->main_security_ctx);
 
2844
  thd->thread_specific_used= false;
 
2845
 
 
2846
  if (opt_bin_log)
 
2847
  {
 
2848
    reset_dynamic(&thd->user_var_events);
 
2849
    thd->user_var_events_alloc= thd->mem_root;
 
2850
  }
 
2851
  thd->clear_error();
 
2852
  thd->main_da.reset_diagnostics_area();
 
2853
  thd->total_warn_count=0;                      // Warnings for this query
 
2854
  thd->rand_used= 0;
 
2855
  thd->sent_row_count= thd->examined_row_count= 0;
 
2856
 
 
2857
  /*
 
2858
    Because we come here only for start of top-statements, binlog format is
 
2859
    constant inside a complex statement (using stored functions) etc.
 
2860
  */
 
2861
  thd->reset_current_stmt_binlog_row_based();
 
2862
 
 
2863
  return;
 
2864
}
 
2865
 
 
2866
 
629
2867
void
630
 
init_select(LEX *lex)
 
2868
mysql_init_select(LEX *lex)
631
2869
{
632
 
  Select_Lex *select_lex= lex->current_select;
 
2870
  SELECT_LEX *select_lex= lex->current_select;
633
2871
  select_lex->init_select();
634
2872
  lex->wild= 0;
635
2873
  if (select_lex == &lex->select_lex)
641
2879
 
642
2880
 
643
2881
bool
644
 
new_select(LEX *lex, bool move_down)
 
2882
mysql_new_select(LEX *lex, bool move_down)
645
2883
{
646
 
  Select_Lex *select_lex;
647
 
  Session *session= lex->session;
648
 
 
649
 
  if (!(select_lex= new (session->mem_root) Select_Lex()))
650
 
    return true;
651
 
 
652
 
  select_lex->select_number= ++session->select_number;
 
2884
  SELECT_LEX *select_lex;
 
2885
  THD *thd= lex->thd;
 
2886
 
 
2887
  if (!(select_lex= new (thd->mem_root) SELECT_LEX()))
 
2888
    return(1);
 
2889
  select_lex->select_number= ++thd->select_number;
653
2890
  select_lex->parent_lex= lex; /* Used in init_query. */
654
2891
  select_lex->init_query();
655
2892
  select_lex->init_select();
656
2893
  lex->nest_level++;
657
 
 
658
2894
  if (lex->nest_level > (int) MAX_SELECT_NESTING)
659
2895
  {
660
2896
    my_error(ER_TOO_HIGH_LEVEL_OF_NESTING_FOR_SELECT,MYF(0),MAX_SELECT_NESTING);
661
2897
    return(1);
662
2898
  }
663
 
 
664
2899
  select_lex->nest_level= lex->nest_level;
665
2900
  if (move_down)
666
2901
  {
667
 
    Select_Lex_Unit *unit;
 
2902
    SELECT_LEX_UNIT *unit;
 
2903
    lex->subqueries= true;
668
2904
    /* first select_lex of subselect or derived table */
669
 
    if (!(unit= new (session->mem_root) Select_Lex_Unit()))
 
2905
    if (!(unit= new (thd->mem_root) SELECT_LEX_UNIT()))
670
2906
      return(1);
671
2907
 
672
2908
    unit->init_query();
673
2909
    unit->init_select();
674
 
    unit->session= session;
 
2910
    unit->thd= thd;
675
2911
    unit->include_down(lex->current_select);
676
2912
    unit->link_next= 0;
677
2913
    unit->link_prev= 0;
687
2923
  {
688
2924
    if (lex->current_select->order_list.first && !lex->current_select->braces)
689
2925
    {
690
 
      my_error(ER_WRONG_USAGE, MYF(0), "UNION", "order_st BY");
691
 
      return true;
 
2926
      my_error(ER_WRONG_USAGE, MYF(0), "UNION", "ORDER BY");
 
2927
      return(1);
692
2928
    }
693
 
 
694
2929
    select_lex->include_neighbour(lex->current_select);
695
 
    Select_Lex_Unit *unit= select_lex->master_unit();
696
 
 
697
 
    if (not unit->fake_select_lex && unit->add_fake_select_lex(lex->session))
698
 
      return true;
699
 
 
700
 
    select_lex->context.outer_context=
 
2930
    SELECT_LEX_UNIT *unit= select_lex->master_unit();                              
 
2931
    if (!unit->fake_select_lex && unit->add_fake_select_lex(lex->thd))
 
2932
      return(1);
 
2933
    select_lex->context.outer_context= 
701
2934
                unit->first_select()->context.outer_context;
702
2935
  }
703
2936
 
704
2937
  select_lex->master_unit()->global_parameters= select_lex;
705
 
  select_lex->include_global((Select_Lex_Node**)&lex->all_selects_list);
 
2938
  select_lex->include_global((st_select_lex_node**)&lex->all_selects_list);
706
2939
  lex->current_select= select_lex;
707
2940
  /*
708
2941
    in subquery is SELECT query and we allow resolution of names in SELECT
709
2942
    list
710
2943
  */
711
2944
  select_lex->context.resolve_in_select_list= true;
712
 
 
713
 
  return false;
 
2945
  return(0);
714
2946
}
715
2947
 
716
2948
/**
723
2955
  @param var_name               Variable name
724
2956
*/
725
2957
 
726
 
void create_select_for_variable(Session *session, const char *var_name)
 
2958
void create_select_for_variable(const char *var_name)
727
2959
{
 
2960
  THD *thd;
728
2961
  LEX *lex;
729
2962
  LEX_STRING tmp, null_lex_string;
730
2963
  Item *var;
731
 
  char buff[MAX_SYS_VAR_LENGTH*2+4+8];
732
 
  char *end= buff;
 
2964
  char buff[MAX_SYS_VAR_LENGTH*2+4+8], *end;
733
2965
 
734
 
  lex= session->getLex();
735
 
  init_select(lex);
 
2966
  thd= current_thd;
 
2967
  lex= thd->lex;
 
2968
  mysql_init_select(lex);
736
2969
  lex->sql_command= SQLCOM_SELECT;
737
2970
  tmp.str= (char*) var_name;
738
2971
  tmp.length=strlen(var_name);
739
 
  memset(&null_lex_string.str, 0, sizeof(null_lex_string));
 
2972
  bzero((char*) &null_lex_string.str, sizeof(null_lex_string));
740
2973
  /*
741
2974
    We set the name of Item to @@session.var_name because that then is used
742
2975
    as the column name in the output.
743
2976
  */
744
 
  if ((var= get_system_var(session, OPT_SESSION, tmp, null_lex_string)))
 
2977
  if ((var= get_system_var(thd, OPT_SESSION, tmp, null_lex_string)))
745
2978
  {
746
 
    end+= snprintf(buff, sizeof(buff), "@@session.%s", var_name);
 
2979
    end= strxmov(buff, "@@session.", var_name, NullS);
747
2980
    var->set_name(buff, end-buff, system_charset_info);
748
 
    session->add_item_to_list(var);
 
2981
    add_item_to_list(thd, var);
749
2982
  }
750
 
}
751
 
 
 
2983
  return;
 
2984
}
 
2985
 
 
2986
 
 
2987
void mysql_init_multi_delete(LEX *lex)
 
2988
{
 
2989
  lex->sql_command=  SQLCOM_DELETE_MULTI;
 
2990
  mysql_init_select(lex);
 
2991
  lex->select_lex.select_limit= 0;
 
2992
  lex->unit.select_limit_cnt= HA_POS_ERROR;
 
2993
  lex->select_lex.table_list.save_and_clear(&lex->auxiliary_table_list);
 
2994
  lex->lock_option= using_update_log ? TL_READ_NO_INSERT : TL_READ;
 
2995
  lex->query_tables= 0;
 
2996
  lex->query_tables_last= &lex->query_tables;
 
2997
}
 
2998
 
 
2999
 
 
3000
/*
 
3001
  When you modify mysql_parse(), you may need to mofify
 
3002
  mysql_test_parse_for_slave() in this same file.
 
3003
*/
752
3004
 
753
3005
/**
754
3006
  Parse a query.
755
3007
 
756
 
  @param       session     Current thread
 
3008
  @param       thd     Current thread
757
3009
  @param       inBuf   Begining of the query text
758
3010
  @param       length  Length of the query text
 
3011
  @param[out]  found_semicolon For multi queries, position of the character of
 
3012
                               the next query in the query text.
759
3013
*/
760
3014
 
761
 
void parse(Session *session, const char *inBuf, uint32_t length)
 
3015
void mysql_parse(THD *thd, const char *inBuf, uint length,
 
3016
                 const char ** found_semicolon)
762
3017
{
763
 
  session->getLex()->start(session);
764
 
 
765
 
  session->reset_for_next_command();
766
 
  /* Check if the Query is Cached if and return true if yes
767
 
   * TODO the plugin has to make sure that the query is cacheble
768
 
   * by setting the query_safe_cache param to TRUE
769
 
   */
770
 
  bool res= true;
771
 
  if (plugin::QueryCache::isCached(session))
772
 
  {
773
 
    res= plugin::QueryCache::sendCachedResultset(session);
774
 
  }
775
 
  if (not res)
776
 
  {
777
 
    return;
778
 
  }
779
 
  LEX *lex= session->getLex();
780
 
  Lex_input_stream lip(session, inBuf, length);
781
 
  bool err= parse_sql(session, &lip);
782
 
  if (!err)
783
 
  {
 
3018
  /*
 
3019
    Warning.
 
3020
    The purpose of query_cache_send_result_to_client() is to lookup the
 
3021
    query in the query cache first, to avoid parsing and executing it.
 
3022
    So, the natural implementation would be to:
 
3023
    - first, call query_cache_send_result_to_client,
 
3024
    - second, if caching failed, initialise the lexical and syntactic parser.
 
3025
    The problem is that the query cache depends on a clean initialization
 
3026
    of (among others) lex->safe_to_cache_query and thd->server_status,
 
3027
    which are reset respectively in
 
3028
    - lex_start()
 
3029
    - mysql_reset_thd_for_next_command()
 
3030
    So, initializing the lexical analyser *before* using the query cache
 
3031
    is required for the cache to work properly.
 
3032
    FIXME: cleanup the dependencies in the code to simplify this.
 
3033
  */
 
3034
  lex_start(thd);
 
3035
  mysql_reset_thd_for_next_command(thd);
 
3036
 
 
3037
  {
 
3038
    LEX *lex= thd->lex;
 
3039
 
 
3040
    Lex_input_stream lip(thd, inBuf, length);
 
3041
 
 
3042
    bool err= parse_sql(thd, &lip, NULL);
 
3043
    *found_semicolon= lip.found_semicolon;
 
3044
 
 
3045
    if (!err)
784
3046
    {
785
 
      if (not session->is_error())
786
3047
      {
787
 
        DRIZZLE_QUERY_EXEC_START(session->getQueryString()->c_str(),
788
 
                                 session->thread_id,
789
 
                                 const_cast<const char *>(session->schema()->c_str()));
790
 
        // Implement Views here --Brian
791
 
        /* Actually execute the query */
792
 
        try 
793
 
        {
794
 
          execute_command(session);
795
 
        }
796
 
        catch (...)
797
 
        {
798
 
          // Just try to catch any random failures that could have come
799
 
          // during execution.
800
 
          DRIZZLE_ABORT;
801
 
        }
802
 
        DRIZZLE_QUERY_EXEC_DONE(0);
 
3048
        if (! thd->is_error())
 
3049
        {
 
3050
          /*
 
3051
            Binlog logs a string starting from thd->query and having length
 
3052
            thd->query_length; so we set thd->query_length correctly (to not
 
3053
            log several statements in one event, when we executed only first).
 
3054
            We set it to not see the ';' (otherwise it would get into binlog
 
3055
            and Query_log_event::print() would give ';;' output).
 
3056
            This also helps display only the current query in SHOW
 
3057
            PROCESSLIST.
 
3058
            Note that we don't need LOCK_thread_count to modify query_length.
 
3059
          */
 
3060
          if (*found_semicolon &&
 
3061
              (thd->query_length= (ulong)(*found_semicolon - thd->query)))
 
3062
            thd->query_length--;
 
3063
          /* Actually execute the query */
 
3064
          mysql_execute_command(thd);
 
3065
        }
803
3066
      }
804
3067
    }
805
 
  }
806
 
  else
807
 
  {
808
 
    assert(session->is_error());
809
 
  }
810
 
  lex->unit.cleanup();
811
 
  session->set_proc_info("freeing items");
812
 
  session->end_statement();
813
 
  session->cleanup_after_query();
814
 
  session->set_end_timer();
815
 
}
 
3068
    else
 
3069
    {
 
3070
      assert(thd->is_error());
 
3071
    }
 
3072
    lex->unit.cleanup();
 
3073
    thd_proc_info(thd, "freeing items");
 
3074
    thd->end_statement();
 
3075
    thd->cleanup_after_query();
 
3076
    assert(thd->change_list.is_empty());
 
3077
  }
 
3078
 
 
3079
  return;
 
3080
}
 
3081
 
 
3082
 
 
3083
#ifdef HAVE_REPLICATION
 
3084
/*
 
3085
  Usable by the replication SQL thread only: just parse a query to know if it
 
3086
  can be ignored because of replicate-*-table rules.
 
3087
 
 
3088
  @retval
 
3089
    0   cannot be ignored
 
3090
  @retval
 
3091
    1   can be ignored
 
3092
*/
 
3093
 
 
3094
bool mysql_test_parse_for_slave(THD *thd, char *inBuf, uint length)
 
3095
{
 
3096
  LEX *lex= thd->lex;
 
3097
  bool error= 0;
 
3098
 
 
3099
  Lex_input_stream lip(thd, inBuf, length);
 
3100
  lex_start(thd);
 
3101
  mysql_reset_thd_for_next_command(thd);
 
3102
 
 
3103
  if (!parse_sql(thd, &lip, NULL) &&
 
3104
      all_tables_not_ok(thd,(TABLE_LIST*) lex->select_lex.table_list.first))
 
3105
    error= 1;                  /* Ignore question */
 
3106
  thd->end_statement();
 
3107
  thd->cleanup_after_query();
 
3108
  return(error);
 
3109
}
 
3110
#endif
816
3111
 
817
3112
 
818
3113
 
823
3118
    Return 0 if ok
824
3119
*/
825
3120
 
826
 
bool add_field_to_list(Session *session, LEX_STRING *field_name, enum_field_types type,
 
3121
bool add_field_to_list(THD *thd, LEX_STRING *field_name, enum_field_types type,
827
3122
                       char *length, char *decimals,
828
 
                       uint32_t type_modifier,
 
3123
                       uint type_modifier,
829
3124
                       enum column_format_type column_format,
830
3125
                       Item *default_value, Item *on_update_value,
831
3126
                       LEX_STRING *comment,
832
3127
                       char *change,
833
 
                       List<String> *interval_list, const CHARSET_INFO * const cs)
 
3128
                       List<String> *interval_list, CHARSET_INFO *cs)
834
3129
{
835
 
  register CreateField *new_field;
836
 
  LEX  *lex= session->getLex();
837
 
  statement::AlterTable *statement= (statement::AlterTable *)lex->statement;
 
3130
  register Create_field *new_field;
 
3131
  LEX  *lex= thd->lex;
838
3132
 
839
3133
  if (check_identifier_name(field_name, ER_TOO_LONG_IDENT))
840
 
    return true;
 
3134
    return(1);                          /* purecov: inspected */
841
3135
 
842
3136
  if (type_modifier & PRI_KEY_FLAG)
843
3137
  {
846
3140
    key= new Key(Key::PRIMARY, null_lex_str,
847
3141
                      &default_key_create_info,
848
3142
                      0, lex->col_list);
849
 
    statement->alter_info.key_list.push_back(key);
850
 
    lex->col_list.clear();
 
3143
    lex->alter_info.key_list.push_back(key);
 
3144
    lex->col_list.empty();
851
3145
  }
852
3146
  if (type_modifier & (UNIQUE_FLAG | UNIQUE_KEY_FLAG))
853
3147
  {
856
3150
    key= new Key(Key::UNIQUE, null_lex_str,
857
3151
                 &default_key_create_info, 0,
858
3152
                 lex->col_list);
859
 
    statement->alter_info.key_list.push_back(key);
860
 
    lex->col_list.clear();
 
3153
    lex->alter_info.key_list.push_back(key);
 
3154
    lex->col_list.empty();
861
3155
  }
862
3156
 
863
3157
  if (default_value)
864
3158
  {
865
 
    /*
 
3159
    /* 
866
3160
      Default value should be literal => basic constants =>
867
3161
      no need fix_fields()
868
 
 
869
 
      We allow only one function as part of default value -
 
3162
      
 
3163
      We allow only one function as part of default value - 
870
3164
      NOW() as default for TIMESTAMP type.
871
3165
    */
872
 
    if (default_value->type() == Item::FUNC_ITEM &&
 
3166
    if (default_value->type() == Item::FUNC_ITEM && 
873
3167
        !(((Item_func*)default_value)->functype() == Item_func::NOW_FUNC &&
874
 
         (type == DRIZZLE_TYPE_TIMESTAMP or type == DRIZZLE_TYPE_MICROTIME)))
 
3168
         type == MYSQL_TYPE_TIMESTAMP))
875
3169
    {
876
3170
      my_error(ER_INVALID_DEFAULT, MYF(0), field_name->str);
877
 
      return true;
 
3171
      return(1);
878
3172
    }
879
3173
    else if (default_value->type() == Item::NULL_ITEM)
880
3174
    {
881
3175
      default_value= 0;
882
 
      if ((type_modifier & (NOT_NULL_FLAG | AUTO_INCREMENT_FLAG)) == NOT_NULL_FLAG)
 
3176
      if ((type_modifier & (NOT_NULL_FLAG | AUTO_INCREMENT_FLAG)) ==
 
3177
          NOT_NULL_FLAG)
883
3178
      {
884
3179
        my_error(ER_INVALID_DEFAULT, MYF(0), field_name->str);
885
 
        return true;
 
3180
        return(1);
886
3181
      }
887
3182
    }
888
3183
    else if (type_modifier & AUTO_INCREMENT_FLAG)
889
3184
    {
890
3185
      my_error(ER_INVALID_DEFAULT, MYF(0), field_name->str);
891
 
      return true;
 
3186
      return(1);
892
3187
    }
893
3188
  }
894
3189
 
895
 
  if (on_update_value && (type != DRIZZLE_TYPE_TIMESTAMP and type != DRIZZLE_TYPE_MICROTIME))
 
3190
  if (on_update_value && type != MYSQL_TYPE_TIMESTAMP)
896
3191
  {
897
3192
    my_error(ER_INVALID_ON_UPDATE, MYF(0), field_name->str);
898
 
    return true;
 
3193
    return(1);
899
3194
  }
900
3195
 
901
 
  if (!(new_field= new CreateField()) ||
902
 
      new_field->init(session, field_name->str, type, length, decimals, type_modifier,
 
3196
  if (!(new_field= new Create_field()) ||
 
3197
      new_field->init(thd, field_name->str, type, length, decimals, type_modifier,
903
3198
                      default_value, on_update_value, comment, change,
904
3199
                      interval_list, cs, 0, column_format))
905
 
    return true;
 
3200
    return(1);
906
3201
 
907
 
  statement->alter_info.create_list.push_back(new_field);
 
3202
  lex->alter_info.create_list.push_back(new_field);
908
3203
  lex->last_field=new_field;
909
 
 
910
 
  return false;
 
3204
  return(0);
 
3205
}
 
3206
 
 
3207
 
 
3208
/** Store position for column in ALTER TABLE .. ADD column. */
 
3209
 
 
3210
void store_position_for_column(const char *name)
 
3211
{
 
3212
  current_thd->lex->last_field->after=my_const_cast(char*) (name);
 
3213
}
 
3214
 
 
3215
bool
 
3216
add_proc_to_list(THD* thd, Item *item)
 
3217
{
 
3218
  ORDER *order;
 
3219
  Item  **item_ptr;
 
3220
 
 
3221
  if (!(order = (ORDER *) thd->alloc(sizeof(ORDER)+sizeof(Item*))))
 
3222
    return 1;
 
3223
  item_ptr = (Item**) (order+1);
 
3224
  *item_ptr= item;
 
3225
  order->item=item_ptr;
 
3226
  order->free_me=0;
 
3227
  thd->lex->proc_list.link_in_list((uchar*) order,(uchar**) &order->next);
 
3228
  return 0;
 
3229
}
 
3230
 
 
3231
 
 
3232
/**
 
3233
  save order by and tables in own lists.
 
3234
*/
 
3235
 
 
3236
bool add_to_list(THD *thd, SQL_LIST &list,Item *item,bool asc)
 
3237
{
 
3238
  ORDER *order;
 
3239
  if (!(order = (ORDER *) thd->alloc(sizeof(ORDER))))
 
3240
    return(1);
 
3241
  order->item_ptr= item;
 
3242
  order->item= &order->item_ptr;
 
3243
  order->asc = asc;
 
3244
  order->free_me=0;
 
3245
  order->used=0;
 
3246
  order->counter_used= 0;
 
3247
  list.link_in_list((uchar*) order,(uchar**) &order->next);
 
3248
  return(0);
911
3249
}
912
3250
 
913
3251
 
927
3265
  @retval
928
3266
      0         Error
929
3267
  @retval
930
 
    \#  Pointer to TableList element added to the total table list
 
3268
    \#  Pointer to TABLE_LIST element added to the total table list
931
3269
*/
932
3270
 
933
 
TableList *Select_Lex::add_table_to_list(Session *session,
934
 
                                         Table_ident *table,
935
 
                                         LEX_STRING *alias,
936
 
                                         const bitset<NUM_OF_TABLE_OPTIONS>& table_options,
937
 
                                         thr_lock_type lock_type,
938
 
                                         List<Index_hint> *index_hints_arg,
939
 
                                         LEX_STRING *option)
 
3271
TABLE_LIST *st_select_lex::add_table_to_list(THD *thd,
 
3272
                                             Table_ident *table,
 
3273
                                             LEX_STRING *alias,
 
3274
                                             ulong table_options,
 
3275
                                             thr_lock_type lock_type,
 
3276
                                             List<Index_hint> *index_hints_arg,
 
3277
                                             LEX_STRING *option)
940
3278
{
941
 
  TableList *ptr;
942
 
  TableList *previous_table_ref; /* The table preceding the current one. */
 
3279
  register TABLE_LIST *ptr;
 
3280
  TABLE_LIST *previous_table_ref; /* The table preceding the current one. */
943
3281
  char *alias_str;
944
 
  LEX *lex= session->getLex();
 
3282
  LEX *lex= thd->lex;
945
3283
 
946
3284
  if (!table)
947
 
    return NULL;                                // End of memory
 
3285
    return(0);                          // End of memory
948
3286
  alias_str= alias ? alias->str : table->table.str;
949
 
  if (! table_options.test(TL_OPTION_ALIAS) &&
 
3287
  if (!test(table_options & TL_OPTION_ALIAS) && 
950
3288
      check_table_name(table->table.str, table->table.length))
951
3289
  {
952
3290
    my_error(ER_WRONG_TABLE_NAME, MYF(0), table->table.str);
953
 
    return NULL;
 
3291
    return(0);
954
3292
  }
955
3293
 
956
 
  if (table->is_derived_table() == false && table->db.str)
 
3294
  if (table->is_derived_table() == false && table->db.str &&
 
3295
      check_db_name(&table->db))
957
3296
  {
958
 
    my_casedn_str(files_charset_info, table->db.str);
959
 
 
960
 
    identifier::Schema schema_identifier(string(table->db.str));
961
 
    if (not schema::check(*session, schema_identifier))
962
 
    {
963
 
 
964
 
      my_error(ER_WRONG_DB_NAME, MYF(0), table->db.str);
965
 
      return NULL;
966
 
    }
 
3297
    my_error(ER_WRONG_DB_NAME, MYF(0), table->db.str);
 
3298
    return(0);
967
3299
  }
968
3300
 
969
3301
  if (!alias)                                   /* Alias is case sensitive */
972
3304
    {
973
3305
      my_message(ER_DERIVED_MUST_HAVE_ALIAS,
974
3306
                 ER(ER_DERIVED_MUST_HAVE_ALIAS), MYF(0));
975
 
      return NULL;
 
3307
      return(0);
976
3308
    }
977
 
    if (!(alias_str= (char*) session->getMemRoot()->duplicate(alias_str,table->table.length+1)))
978
 
      return NULL;
 
3309
    if (!(alias_str= (char*) thd->memdup(alias_str,table->table.length+1)))
 
3310
      return(0);
979
3311
  }
980
 
  if (!(ptr = (TableList *) session->calloc(sizeof(TableList))))
981
 
    return NULL;
982
 
 
 
3312
  if (!(ptr = (TABLE_LIST *) thd->calloc(sizeof(TABLE_LIST))))
 
3313
    return(0);                          /* purecov: inspected */
983
3314
  if (table->db.str)
984
3315
  {
985
 
    ptr->setIsFqtn(true);
986
 
    ptr->setSchemaName(table->db.str);
 
3316
    ptr->is_fqtn= true;
 
3317
    ptr->db= table->db.str;
987
3318
    ptr->db_length= table->db.length;
988
3319
  }
989
 
  else if (lex->copy_db_to(ptr->getSchemaNamePtr(), &ptr->db_length))
990
 
    return NULL;
 
3320
  else if (lex->copy_db_to(&ptr->db, &ptr->db_length))
 
3321
    return(0);
991
3322
  else
992
 
    ptr->setIsFqtn(false);
 
3323
    ptr->is_fqtn= false;
993
3324
 
994
3325
  ptr->alias= alias_str;
995
 
  ptr->setIsAlias(alias ? true : false);
996
 
  ptr->setTableName(table->table.str);
 
3326
  ptr->is_alias= alias ? true : false;
 
3327
  if (lower_case_table_names && table->table.length)
 
3328
    table->table.length= my_casedn_str(files_charset_info, table->table.str);
 
3329
  ptr->table_name=table->table.str;
997
3330
  ptr->table_name_length=table->table.length;
998
3331
  ptr->lock_type=   lock_type;
999
 
  ptr->force_index= table_options.test(TL_OPTION_FORCE_INDEX);
1000
 
  ptr->ignore_leaves= table_options.test(TL_OPTION_IGNORE_LEAVES);
 
3332
  ptr->lock_timeout= -1;      /* default timeout */
 
3333
  ptr->lock_transactional= 1; /* allow transactional locks */
 
3334
  ptr->updating=    test(table_options & TL_OPTION_UPDATING);
 
3335
  ptr->force_index= test(table_options & TL_OPTION_FORCE_INDEX);
 
3336
  ptr->ignore_leaves= test(table_options & TL_OPTION_IGNORE_LEAVES);
1001
3337
  ptr->derived=     table->sel;
 
3338
  if (!ptr->derived && !my_strcasecmp(system_charset_info, ptr->db,
 
3339
                                      INFORMATION_SCHEMA_NAME.str))
 
3340
  {
 
3341
    ST_SCHEMA_TABLE *schema_table= find_schema_table(thd, ptr->table_name);
 
3342
    if (!schema_table ||
 
3343
        (schema_table->hidden && 
 
3344
         ((sql_command_flags[lex->sql_command] & CF_STATUS_COMMAND) == 0 || 
 
3345
          /*
 
3346
            this check is used for show columns|keys from I_S hidden table
 
3347
          */
 
3348
          lex->sql_command == SQLCOM_SHOW_FIELDS ||
 
3349
          lex->sql_command == SQLCOM_SHOW_KEYS)))
 
3350
    {
 
3351
      my_error(ER_UNKNOWN_TABLE, MYF(0),
 
3352
               ptr->table_name, INFORMATION_SCHEMA_NAME.str);
 
3353
      return(0);
 
3354
    }
 
3355
    ptr->schema_table_name= ptr->table_name;
 
3356
    ptr->schema_table= schema_table;
 
3357
  }
1002
3358
  ptr->select_lex=  lex->current_select;
 
3359
  ptr->cacheable_table= 1;
1003
3360
  ptr->index_hints= index_hints_arg;
1004
3361
  ptr->option= option ? option->str : 0;
1005
3362
  /* check that used name is unique */
1006
3363
  if (lock_type != TL_IGNORE)
1007
3364
  {
1008
 
    TableList *first_table= (TableList*) table_list.first;
1009
 
    for (TableList *tables= first_table ;
 
3365
    TABLE_LIST *first_table= (TABLE_LIST*) table_list.first;
 
3366
    for (TABLE_LIST *tables= first_table ;
1010
3367
         tables ;
1011
3368
         tables=tables->next_local)
1012
3369
    {
1013
 
      if (not my_strcasecmp(table_alias_charset, alias_str, tables->alias) &&
1014
 
          not my_strcasecmp(system_charset_info, ptr->getSchemaName(), tables->getSchemaName()))
 
3370
      if (!my_strcasecmp(table_alias_charset, alias_str, tables->alias) &&
 
3371
          !strcmp(ptr->db, tables->db))
1015
3372
      {
1016
 
        my_error(ER_NONUNIQ_TABLE, MYF(0), alias_str);
1017
 
        return NULL;
 
3373
        my_error(ER_NONUNIQ_TABLE, MYF(0), alias_str); /* purecov: tested */
 
3374
        return(0);                              /* purecov: tested */
1018
3375
      }
1019
3376
    }
1020
3377
  }
1022
3379
  if (table_list.elements > 0)
1023
3380
  {
1024
3381
    /*
1025
 
      table_list.next points to the last inserted TableList->next_local'
 
3382
      table_list.next points to the last inserted TABLE_LIST->next_local'
1026
3383
      element
1027
3384
      We don't use the offsetof() macro here to avoid warnings from gcc
1028
3385
    */
1029
 
    previous_table_ref= (TableList*) ((char*) table_list.next -
 
3386
    previous_table_ref= (TABLE_LIST*) ((char*) table_list.next -
1030
3387
                                       ((char*) &(ptr->next_local) -
1031
3388
                                        (char*) ptr));
1032
3389
    /*
1033
3390
      Set next_name_resolution_table of the previous table reference to point
1034
3391
      to the current table reference. In effect the list
1035
 
      TableList::next_name_resolution_table coincides with
1036
 
      TableList::next_local. Later this may be changed in
 
3392
      TABLE_LIST::next_name_resolution_table coincides with
 
3393
      TABLE_LIST::next_local. Later this may be changed in
1037
3394
      store_top_level_join_columns() for NATURAL/USING joins.
1038
3395
    */
1039
3396
    previous_table_ref->next_name_resolution_table= ptr;
1045
3402
    previous table reference to 'ptr'. Here we also add one element to the
1046
3403
    list 'table_list'.
1047
3404
  */
1048
 
  table_list.link_in_list((unsigned char*) ptr, (unsigned char**) &ptr->next_local);
 
3405
  table_list.link_in_list((uchar*) ptr, (uchar**) &ptr->next_local);
1049
3406
  ptr->next_name_resolution_table= NULL;
1050
3407
  /* Link table in global list (all used tables) */
1051
3408
  lex->add_to_query_tables(ptr);
1052
 
  return ptr;
 
3409
  return(ptr);
1053
3410
}
1054
3411
 
1055
3412
 
1056
3413
/**
1057
3414
  Initialize a new table list for a nested join.
1058
3415
 
1059
 
    The function initializes a structure of the TableList type
 
3416
    The function initializes a structure of the TABLE_LIST type
1060
3417
    for a nested join. It sets up its nested join list as empty.
1061
3418
    The created structure is added to the front of the current
1062
 
    join list in the Select_Lex object. Then the function
 
3419
    join list in the st_select_lex object. Then the function
1063
3420
    changes the current nest level for joins to refer to the newly
1064
3421
    created empty list after having saved the info on the old level
1065
3422
    in the initialized structure.
1066
3423
 
1067
 
  @param session         current thread
 
3424
  @param thd         current thread
1068
3425
 
1069
3426
  @retval
1070
3427
    0   if success
1072
3429
    1   otherwise
1073
3430
*/
1074
3431
 
1075
 
bool Select_Lex::init_nested_join(Session *session)
 
3432
bool st_select_lex::init_nested_join(THD *thd)
1076
3433
{
1077
 
  TableList *ptr;
1078
 
  NestedJoin *nested_join;
1079
 
 
1080
 
  if (!(ptr= (TableList*) session->calloc(ALIGN_SIZE(sizeof(TableList))+
1081
 
                                       sizeof(NestedJoin))))
1082
 
    return true;
1083
 
  ptr->setNestedJoin(((NestedJoin*) ((unsigned char*) ptr + ALIGN_SIZE(sizeof(TableList)))));
1084
 
  nested_join= ptr->getNestedJoin();
 
3434
  TABLE_LIST *ptr;
 
3435
  NESTED_JOIN *nested_join;
 
3436
 
 
3437
  if (!(ptr= (TABLE_LIST*) thd->calloc(ALIGN_SIZE(sizeof(TABLE_LIST))+
 
3438
                                       sizeof(NESTED_JOIN))))
 
3439
    return(1);
 
3440
  nested_join= ptr->nested_join=
 
3441
    ((NESTED_JOIN*) ((uchar*) ptr + ALIGN_SIZE(sizeof(TABLE_LIST))));
 
3442
 
1085
3443
  join_list->push_front(ptr);
1086
 
  ptr->setEmbedding(embedding);
1087
 
  ptr->setJoinList(join_list);
 
3444
  ptr->embedding= embedding;
 
3445
  ptr->join_list= join_list;
1088
3446
  ptr->alias= (char*) "(nested_join)";
1089
3447
  embedding= ptr;
1090
3448
  join_list= &nested_join->join_list;
1091
 
  join_list->clear();
1092
 
  return false;
 
3449
  join_list->empty();
 
3450
  return(0);
1093
3451
}
1094
3452
 
1095
3453
 
1100
3458
    If the current level contains only one member, the function
1101
3459
    moves it one level up, eliminating the nest.
1102
3460
 
1103
 
  @param session         current thread
 
3461
  @param thd         current thread
1104
3462
 
1105
3463
  @return
1106
 
    - Pointer to TableList element added to the total table list, if success
 
3464
    - Pointer to TABLE_LIST element added to the total table list, if success
1107
3465
    - 0, otherwise
1108
3466
*/
1109
3467
 
1110
 
TableList *Select_Lex::end_nested_join(Session *)
 
3468
TABLE_LIST *st_select_lex::end_nested_join(THD *thd __attribute__((__unused__)))
1111
3469
{
1112
 
  TableList *ptr;
1113
 
  NestedJoin *nested_join;
 
3470
  TABLE_LIST *ptr;
 
3471
  NESTED_JOIN *nested_join;
1114
3472
 
1115
3473
  assert(embedding);
1116
3474
  ptr= embedding;
1117
 
  join_list= ptr->getJoinList();
1118
 
  embedding= ptr->getEmbedding();
1119
 
  nested_join= ptr->getNestedJoin();
 
3475
  join_list= ptr->join_list;
 
3476
  embedding= ptr->embedding;
 
3477
  nested_join= ptr->nested_join;
1120
3478
  if (nested_join->join_list.elements == 1)
1121
3479
  {
1122
 
    TableList *embedded= nested_join->join_list.head();
 
3480
    TABLE_LIST *embedded= nested_join->join_list.head();
1123
3481
    join_list->pop();
1124
 
    embedded->setJoinList(join_list);
1125
 
    embedded->setEmbedding(embedding);
 
3482
    embedded->join_list= join_list;
 
3483
    embedded->embedding= embedding;
1126
3484
    join_list->push_front(embedded);
1127
3485
    ptr= embedded;
1128
3486
  }
1129
3487
  else if (nested_join->join_list.elements == 0)
1130
3488
  {
1131
3489
    join_list->pop();
1132
 
    ptr= NULL;                                     // return value
 
3490
    ptr= 0;                                     // return value
1133
3491
  }
1134
 
  return ptr;
 
3492
  return(ptr);
1135
3493
}
1136
3494
 
1137
3495
 
1140
3498
 
1141
3499
    The function nest last join operation as if it was enclosed in braces.
1142
3500
 
1143
 
  @param session         current thread
 
3501
  @param thd         current thread
1144
3502
 
1145
3503
  @retval
1146
3504
    0  Error
1147
3505
  @retval
1148
 
    \#  Pointer to TableList element created for the new nested join
 
3506
    \#  Pointer to TABLE_LIST element created for the new nested join
1149
3507
*/
1150
3508
 
1151
 
TableList *Select_Lex::nest_last_join(Session *session)
 
3509
TABLE_LIST *st_select_lex::nest_last_join(THD *thd)
1152
3510
{
1153
 
  TableList *ptr;
1154
 
  NestedJoin *nested_join;
1155
 
  List<TableList> *embedded_list;
1156
 
 
1157
 
  if (!(ptr= (TableList*) session->calloc(ALIGN_SIZE(sizeof(TableList))+
1158
 
                                          sizeof(NestedJoin))))
1159
 
    return NULL;
1160
 
  ptr->setNestedJoin(((NestedJoin*) ((unsigned char*) ptr + ALIGN_SIZE(sizeof(TableList)))));
1161
 
  nested_join= ptr->getNestedJoin();
1162
 
  ptr->setEmbedding(embedding);
1163
 
  ptr->setJoinList(join_list);
 
3511
  TABLE_LIST *ptr;
 
3512
  NESTED_JOIN *nested_join;
 
3513
  List<TABLE_LIST> *embedded_list;
 
3514
 
 
3515
  if (!(ptr= (TABLE_LIST*) thd->calloc(ALIGN_SIZE(sizeof(TABLE_LIST))+
 
3516
                                       sizeof(NESTED_JOIN))))
 
3517
    return(0);
 
3518
  nested_join= ptr->nested_join=
 
3519
    ((NESTED_JOIN*) ((uchar*) ptr + ALIGN_SIZE(sizeof(TABLE_LIST))));
 
3520
 
 
3521
  ptr->embedding= embedding;
 
3522
  ptr->join_list= join_list;
1164
3523
  ptr->alias= (char*) "(nest_last_join)";
1165
3524
  embedded_list= &nested_join->join_list;
1166
 
  embedded_list->clear();
 
3525
  embedded_list->empty();
1167
3526
 
1168
 
  for (uint32_t i=0; i < 2; i++)
 
3527
  for (uint i=0; i < 2; i++)
1169
3528
  {
1170
 
    TableList *table= join_list->pop();
1171
 
    table->setJoinList(embedded_list);
1172
 
    table->setEmbedding(ptr);
 
3529
    TABLE_LIST *table= join_list->pop();
 
3530
    table->join_list= embedded_list;
 
3531
    table->embedding= ptr;
1173
3532
    embedded_list->push_back(table);
1174
3533
    if (table->natural_join)
1175
3534
    {
1184
3543
  }
1185
3544
  join_list->push_front(ptr);
1186
3545
  nested_join->used_tables= nested_join->not_null_tables= (table_map) 0;
1187
 
  return ptr;
 
3546
  return(ptr);
1188
3547
}
1189
3548
 
1190
3549
 
1192
3551
  Add a table to the current join list.
1193
3552
 
1194
3553
    The function puts a table in front of the current join list
1195
 
    of Select_Lex object.
 
3554
    of st_select_lex object.
1196
3555
    Thus, joined tables are put into this list in the reverse order
1197
3556
    (the most outer join operation follows first).
1198
3557
 
1202
3561
    None
1203
3562
*/
1204
3563
 
1205
 
void Select_Lex::add_joined_table(TableList *table)
 
3564
void st_select_lex::add_joined_table(TABLE_LIST *table)
1206
3565
{
1207
3566
  join_list->push_front(table);
1208
 
  table->setJoinList(join_list);
1209
 
  table->setEmbedding(embedding);
 
3567
  table->join_list= join_list;
 
3568
  table->embedding= embedding;
 
3569
  return;
1210
3570
}
1211
3571
 
1212
3572
 
1234
3594
      SELECT * FROM t3 LEFT JOIN (t1 LEFT JOIN t2 ON on_expr2) ON on_expr1
1235
3595
   @endverbatim
1236
3596
 
1237
 
  @param session         current thread
 
3597
  @param thd         current thread
1238
3598
 
1239
3599
  @return
1240
3600
    - Pointer to the table representing the inner table, if success
1241
3601
    - 0, otherwise
1242
3602
*/
1243
3603
 
1244
 
TableList *Select_Lex::convert_right_join()
 
3604
TABLE_LIST *st_select_lex::convert_right_join()
1245
3605
{
1246
 
  TableList *tab2= join_list->pop();
1247
 
  TableList *tab1= join_list->pop();
 
3606
  TABLE_LIST *tab2= join_list->pop();
 
3607
  TABLE_LIST *tab1= join_list->pop();
1248
3608
 
1249
3609
  join_list->push_front(tab2);
1250
3610
  join_list->push_front(tab1);
1251
3611
  tab1->outer_join|= JOIN_TYPE_RIGHT;
1252
3612
 
1253
 
  return tab1;
 
3613
  return(tab1);
1254
3614
}
1255
3615
 
1256
3616
/**
1264
3624
    query
1265
3625
*/
1266
3626
 
1267
 
void Select_Lex::set_lock_for_tables(thr_lock_type lock_type)
 
3627
void st_select_lex::set_lock_for_tables(thr_lock_type lock_type)
1268
3628
{
1269
 
  for (TableList *tables= (TableList*) table_list.first;
 
3629
  bool for_update= lock_type >= TL_READ_NO_INSERT;
 
3630
 
 
3631
  for (TABLE_LIST *tables= (TABLE_LIST*) table_list.first;
1270
3632
       tables;
1271
3633
       tables= tables->next_local)
1272
3634
  {
1273
3635
    tables->lock_type= lock_type;
 
3636
    tables->updating=  for_update;
1274
3637
  }
 
3638
  return;
1275
3639
}
1276
3640
 
1277
3641
 
1278
3642
/**
1279
 
  Create a fake Select_Lex for a unit.
 
3643
  Create a fake SELECT_LEX for a unit.
1280
3644
 
1281
 
    The method create a fake Select_Lex object for a unit.
 
3645
    The method create a fake SELECT_LEX object for a unit.
1282
3646
    This object is created for any union construct containing a union
1283
3647
    operation and also for any single select union construct of the form
1284
3648
    @verbatim
1285
 
    (SELECT ... ORDER BY order_list [LIMIT n]) ORDER BY ...
 
3649
    (SELECT ... ORDER BY order_list [LIMIT n]) ORDER BY ... 
1286
3650
    @endvarbatim
1287
3651
    or of the form
1288
3652
    @varbatim
1289
3653
    (SELECT ... ORDER BY LIMIT n) ORDER BY ...
1290
3654
    @endvarbatim
1291
 
 
1292
 
  @param session_arg               thread handle
 
3655
  
 
3656
  @param thd_arg                   thread handle
1293
3657
 
1294
3658
  @note
1295
3659
    The object is used to retrieve rows from the temporary table
1301
3665
    0     on success
1302
3666
*/
1303
3667
 
1304
 
bool Select_Lex_Unit::add_fake_select_lex(Session *session_arg)
 
3668
bool st_select_lex_unit::add_fake_select_lex(THD *thd_arg)
1305
3669
{
1306
 
  Select_Lex *first_sl= first_select();
 
3670
  SELECT_LEX *first_sl= first_select();
1307
3671
  assert(!fake_select_lex);
1308
3672
 
1309
 
  if (!(fake_select_lex= new (session_arg->mem_root) Select_Lex()))
 
3673
  if (!(fake_select_lex= new (thd_arg->mem_root) SELECT_LEX()))
1310
3674
      return(1);
1311
 
  fake_select_lex->include_standalone(this,
1312
 
                                      (Select_Lex_Node**)&fake_select_lex);
 
3675
  fake_select_lex->include_standalone(this, 
 
3676
                                      (SELECT_LEX_NODE**)&fake_select_lex);
1313
3677
  fake_select_lex->select_number= INT_MAX;
1314
 
  fake_select_lex->parent_lex= session_arg->getLex(); /* Used in init_query. */
 
3678
  fake_select_lex->parent_lex= thd_arg->lex; /* Used in init_query. */
1315
3679
  fake_select_lex->make_empty_select();
1316
3680
  fake_select_lex->linkage= GLOBAL_OPTIONS_TYPE;
1317
3681
  fake_select_lex->select_limit= 0;
1323
3687
 
1324
3688
  if (!is_union())
1325
3689
  {
1326
 
    /*
1327
 
      This works only for
 
3690
    /* 
 
3691
      This works only for 
1328
3692
      (SELECT ... ORDER BY list [LIMIT n]) ORDER BY order_list [LIMIT m],
1329
3693
      (SELECT ... LIMIT n) ORDER BY order_list [LIMIT m]
1330
3694
      just before the parser starts processing order_list
1331
 
    */
 
3695
    */ 
1332
3696
    global_parameters= fake_select_lex;
1333
3697
    fake_select_lex->no_table_names_allowed= 1;
1334
 
    session_arg->getLex()->current_select= fake_select_lex;
 
3698
    thd_arg->lex->current_select= fake_select_lex;
1335
3699
  }
1336
 
  session_arg->getLex()->pop_context();
 
3700
  thd_arg->lex->pop_context();
1337
3701
  return(0);
1338
3702
}
1339
3703
 
1347
3711
    to be used for name resolution, and push the newly created
1348
3712
    context to the stack of contexts of the query.
1349
3713
 
1350
 
  @param session       pointer to current thread
 
3714
  @param thd       pointer to current thread
1351
3715
  @param left_op   left  operand of the JOIN
1352
3716
  @param right_op  rigth operand of the JOIN
1353
3717
 
1358
3722
*/
1359
3723
 
1360
3724
bool
1361
 
push_new_name_resolution_context(Session *session,
1362
 
                                 TableList *left_op, TableList *right_op)
 
3725
push_new_name_resolution_context(THD *thd,
 
3726
                                 TABLE_LIST *left_op, TABLE_LIST *right_op)
1363
3727
{
1364
3728
  Name_resolution_context *on_context;
1365
 
  if (!(on_context= new (session->mem_root) Name_resolution_context))
 
3729
  if (!(on_context= new (thd->mem_root) Name_resolution_context))
1366
3730
    return true;
1367
3731
  on_context->init();
1368
3732
  on_context->first_name_resolution_table=
1369
3733
    left_op->first_leaf_for_name_resolution();
1370
3734
  on_context->last_name_resolution_table=
1371
3735
    right_op->last_leaf_for_name_resolution();
1372
 
  return session->getLex()->push_context(on_context);
 
3736
  return thd->lex->push_context(on_context);
1373
3737
}
1374
3738
 
1375
3739
 
1387
3751
    true   if all is OK
1388
3752
*/
1389
3753
 
1390
 
void add_join_on(TableList *b, Item *expr)
 
3754
void add_join_on(TABLE_LIST *b, Item *expr)
1391
3755
{
1392
3756
  if (expr)
1393
3757
  {
1440
3804
  @param using_fields    Field names from USING clause
1441
3805
*/
1442
3806
 
1443
 
void add_join_natural(TableList *a, TableList *b, List<String> *using_fields,
1444
 
                      Select_Lex *lex)
 
3807
void add_join_natural(TABLE_LIST *a, TABLE_LIST *b, List<String> *using_fields,
 
3808
                      SELECT_LEX *lex)
1445
3809
{
1446
3810
  b->natural_join= a;
1447
3811
  lex->prev_join_using= using_fields;
1449
3813
 
1450
3814
 
1451
3815
/**
 
3816
  Reload/resets privileges and the different caches.
 
3817
 
 
3818
  @param thd Thread handler (can be NULL!)
 
3819
  @param options What should be reset/reloaded (tables, privileges, slave...)
 
3820
  @param tables Tables to flush (if any)
 
3821
  @param write_to_binlog True if we can write to the binlog.
 
3822
               
 
3823
  @note Depending on 'options', it may be very bad to write the
 
3824
    query to the binlog (e.g. FLUSH SLAVE); this is a
 
3825
    pointer where reload_cache() will put 0 if
 
3826
    it thinks we really should not write to the binlog.
 
3827
    Otherwise it will put 1.
 
3828
 
 
3829
  @return Error status code
 
3830
    @retval 0 Ok
 
3831
    @retval !=0  Error; thd->killed is set or thd->is_error() is true
 
3832
*/
 
3833
 
 
3834
bool reload_cache(THD *thd, ulong options, TABLE_LIST *tables,
 
3835
                          bool *write_to_binlog)
 
3836
{
 
3837
  bool result=0;
 
3838
  select_errors=0;                              /* Write if more errors */
 
3839
  bool tmp_write_to_binlog= 1;
 
3840
 
 
3841
  assert(!thd || !thd->in_sub_stmt);
 
3842
 
 
3843
  if (options & REFRESH_LOG)
 
3844
  {
 
3845
    /*
 
3846
      Flush the normal query log, the update log, the binary log,
 
3847
      the slow query log, the relay log (if it exists) and the log
 
3848
      tables.
 
3849
    */
 
3850
 
 
3851
    /*
 
3852
      Writing this command to the binlog may result in infinite loops
 
3853
      when doing mysqlbinlog|mysql, and anyway it does not really make
 
3854
      sense to log it automatically (would cause more trouble to users
 
3855
      than it would help them)
 
3856
    */
 
3857
    tmp_write_to_binlog= 0;
 
3858
    if( mysql_bin_log.is_open() )
 
3859
    {
 
3860
      mysql_bin_log.rotate_and_purge(RP_FORCE_ROTATE);
 
3861
    }
 
3862
    pthread_mutex_lock(&LOCK_active_mi);
 
3863
    rotate_relay_log(active_mi);
 
3864
    pthread_mutex_unlock(&LOCK_active_mi);
 
3865
 
 
3866
    /* flush slow and general logs */
 
3867
    logger.flush_logs(thd);
 
3868
 
 
3869
    if (ha_flush_logs(NULL))
 
3870
      result=1;
 
3871
    if (flush_error_log())
 
3872
      result=1;
 
3873
  }
 
3874
  /*
 
3875
    Note that if REFRESH_READ_LOCK bit is set then REFRESH_TABLES is set too
 
3876
    (see sql_yacc.yy)
 
3877
  */
 
3878
  if (options & (REFRESH_TABLES | REFRESH_READ_LOCK)) 
 
3879
  {
 
3880
    if ((options & REFRESH_READ_LOCK) && thd)
 
3881
    {
 
3882
      /*
 
3883
        We must not try to aspire a global read lock if we have a write
 
3884
        locked table. This would lead to a deadlock when trying to
 
3885
        reopen (and re-lock) the table after the flush.
 
3886
      */
 
3887
      if (thd->locked_tables)
 
3888
      {
 
3889
        THR_LOCK_DATA **lock_p= thd->locked_tables->locks;
 
3890
        THR_LOCK_DATA **end_p= lock_p + thd->locked_tables->lock_count;
 
3891
 
 
3892
        for (; lock_p < end_p; lock_p++)
 
3893
        {
 
3894
          if ((*lock_p)->type >= TL_WRITE_ALLOW_WRITE)
 
3895
          {
 
3896
            my_error(ER_LOCK_OR_ACTIVE_TRANSACTION, MYF(0));
 
3897
            return 1;
 
3898
          }
 
3899
        }
 
3900
      }
 
3901
      /*
 
3902
        Writing to the binlog could cause deadlocks, as we don't log
 
3903
        UNLOCK TABLES
 
3904
      */
 
3905
      tmp_write_to_binlog= 0;
 
3906
      if (lock_global_read_lock(thd))
 
3907
        return 1;                               // Killed
 
3908
      result= close_cached_tables(thd, tables, false, (options & REFRESH_FAST) ?
 
3909
                                  false : true, true);
 
3910
      if (make_global_read_lock_block_commit(thd)) // Killed
 
3911
      {
 
3912
        /* Don't leave things in a half-locked state */
 
3913
        unlock_global_read_lock(thd);
 
3914
        return 1;
 
3915
      }
 
3916
    }
 
3917
    else
 
3918
      result= close_cached_tables(thd, tables, false, (options & REFRESH_FAST) ?
 
3919
                                  false : true, false);
 
3920
    my_dbopt_cleanup();
 
3921
  }
 
3922
  if (thd && (options & REFRESH_STATUS))
 
3923
    refresh_status(thd);
 
3924
  if (options & REFRESH_THREADS)
 
3925
    flush_thread_cache();
 
3926
  if (options & REFRESH_MASTER)
 
3927
  {
 
3928
    assert(thd);
 
3929
    tmp_write_to_binlog= 0;
 
3930
    if (reset_master(thd))
 
3931
    {
 
3932
      result=1;
 
3933
    }
 
3934
  }
 
3935
 if (options & REFRESH_SLAVE)
 
3936
 {
 
3937
   tmp_write_to_binlog= 0;
 
3938
   pthread_mutex_lock(&LOCK_active_mi);
 
3939
   if (reset_slave(thd, active_mi))
 
3940
     result=1;
 
3941
   pthread_mutex_unlock(&LOCK_active_mi);
 
3942
 }
 
3943
 *write_to_binlog= tmp_write_to_binlog;
 
3944
 return result;
 
3945
}
 
3946
 
 
3947
 
 
3948
/**
 
3949
  kill on thread.
 
3950
 
 
3951
  @param thd                    Thread class
 
3952
  @param id                     Thread id
 
3953
  @param only_kill_query        Should it kill the query or the connection
 
3954
 
 
3955
  @note
 
3956
    This is written such that we have a short lock on LOCK_thread_count
 
3957
*/
 
3958
 
 
3959
uint kill_one_thread(THD *thd __attribute__((__unused__)),
 
3960
                     ulong id, bool only_kill_query)
 
3961
{
 
3962
  THD *tmp;
 
3963
  uint error=ER_NO_SUCH_THREAD;
 
3964
  VOID(pthread_mutex_lock(&LOCK_thread_count)); // For unlink from list
 
3965
  I_List_iterator<THD> it(threads);
 
3966
  while ((tmp=it++))
 
3967
  {
 
3968
    if (tmp->command == COM_DAEMON)
 
3969
      continue;
 
3970
    if (tmp->thread_id == id)
 
3971
    {
 
3972
      pthread_mutex_lock(&tmp->LOCK_delete);    // Lock from delete
 
3973
      break;
 
3974
    }
 
3975
  }
 
3976
  VOID(pthread_mutex_unlock(&LOCK_thread_count));
 
3977
  if (tmp)
 
3978
  {
 
3979
    tmp->awake(only_kill_query ? THD::KILL_QUERY : THD::KILL_CONNECTION);
 
3980
    error=0;
 
3981
    pthread_mutex_unlock(&tmp->LOCK_delete);
 
3982
  }
 
3983
  return(error);
 
3984
}
 
3985
 
 
3986
 
 
3987
/*
 
3988
  kills a thread and sends response
 
3989
 
 
3990
  SYNOPSIS
 
3991
    sql_kill()
 
3992
    thd                 Thread class
 
3993
    id                  Thread id
 
3994
    only_kill_query     Should it kill the query or the connection
 
3995
*/
 
3996
 
 
3997
void sql_kill(THD *thd, ulong id, bool only_kill_query)
 
3998
{
 
3999
  uint error;
 
4000
  if (!(error= kill_one_thread(thd, id, only_kill_query)))
 
4001
    my_ok(thd);
 
4002
  else
 
4003
    my_error(error, MYF(0), id);
 
4004
}
 
4005
 
 
4006
 
 
4007
/** If pointer is not a null pointer, append filename to it. */
 
4008
 
 
4009
bool append_file_to_dir(THD *thd, const char **filename_ptr,
 
4010
                        const char *table_name)
 
4011
{
 
4012
  char buff[FN_REFLEN],*ptr, *end;
 
4013
  if (!*filename_ptr)
 
4014
    return 0;                                   // nothing to do
 
4015
 
 
4016
  /* Check that the filename is not too long and it's a hard path */
 
4017
  if (strlen(*filename_ptr)+strlen(table_name) >= FN_REFLEN-1 ||
 
4018
      !test_if_hard_path(*filename_ptr))
 
4019
  {
 
4020
    my_error(ER_WRONG_TABLE_NAME, MYF(0), *filename_ptr);
 
4021
    return 1;
 
4022
  }
 
4023
  /* Fix is using unix filename format on dos */
 
4024
  strmov(buff,*filename_ptr);
 
4025
  end=convert_dirname(buff, *filename_ptr, NullS);
 
4026
  if (!(ptr= (char*) thd->alloc((size_t) (end-buff) + strlen(table_name)+1)))
 
4027
    return 1;                                   // End of memory
 
4028
  *filename_ptr=ptr;
 
4029
  strxmov(ptr,buff,table_name,NullS);
 
4030
  return 0;
 
4031
}
 
4032
 
 
4033
 
 
4034
/**
1452
4035
  Check if the select is a simple select (not an union).
1453
4036
 
1454
4037
  @retval
1457
4040
    1   error   ; In this case the error messege is sent to the client
1458
4041
*/
1459
4042
 
1460
 
bool check_simple_select(Session::pointer session)
 
4043
bool check_simple_select()
1461
4044
{
1462
 
  if (session->getLex()->current_select != &session->getLex()->select_lex)
 
4045
  THD *thd= current_thd;
 
4046
  LEX *lex= thd->lex;
 
4047
  if (lex->current_select != &lex->select_lex)
1463
4048
  {
1464
4049
    char command[80];
1465
 
    Lex_input_stream *lip= session->m_lip;
1466
 
    strncpy(command, lip->yylval->symbol.str,
1467
 
            min(lip->yylval->symbol.length, (uint32_t)(sizeof(command)-1)));
1468
 
    command[min(lip->yylval->symbol.length, (uint32_t)(sizeof(command)-1))]=0;
 
4050
    Lex_input_stream *lip= thd->m_lip;
 
4051
    strmake(command, lip->yylval->symbol.str,
 
4052
            min(lip->yylval->symbol.length, sizeof(command)-1));
1469
4053
    my_error(ER_CANT_USE_OPTION_HERE, MYF(0), command);
1470
4054
    return 1;
1471
4055
  }
1473
4057
}
1474
4058
 
1475
4059
 
 
4060
Comp_creator *comp_eq_creator(bool invert)
 
4061
{
 
4062
  return invert?(Comp_creator *)&ne_creator:(Comp_creator *)&eq_creator;
 
4063
}
 
4064
 
 
4065
 
 
4066
Comp_creator *comp_ge_creator(bool invert)
 
4067
{
 
4068
  return invert?(Comp_creator *)&lt_creator:(Comp_creator *)&ge_creator;
 
4069
}
 
4070
 
 
4071
 
 
4072
Comp_creator *comp_gt_creator(bool invert)
 
4073
{
 
4074
  return invert?(Comp_creator *)&le_creator:(Comp_creator *)&gt_creator;
 
4075
}
 
4076
 
 
4077
 
 
4078
Comp_creator *comp_le_creator(bool invert)
 
4079
{
 
4080
  return invert?(Comp_creator *)&gt_creator:(Comp_creator *)&le_creator;
 
4081
}
 
4082
 
 
4083
 
 
4084
Comp_creator *comp_lt_creator(bool invert)
 
4085
{
 
4086
  return invert?(Comp_creator *)&ge_creator:(Comp_creator *)&lt_creator;
 
4087
}
 
4088
 
 
4089
 
 
4090
Comp_creator *comp_ne_creator(bool invert)
 
4091
{
 
4092
  return invert?(Comp_creator *)&eq_creator:(Comp_creator *)&ne_creator;
 
4093
}
 
4094
 
 
4095
 
1476
4096
/**
1477
4097
  Construct ALL/ANY/SOME subquery Item.
1478
4098
 
1485
4105
    constructed Item (or 0 if out of memory)
1486
4106
*/
1487
4107
Item * all_any_subquery_creator(Item *left_expr,
1488
 
                                chooser_compare_func_creator cmp,
1489
 
                                bool all,
1490
 
                                Select_Lex *select_lex)
 
4108
                                chooser_compare_func_creator cmp,
 
4109
                                bool all,
 
4110
                                SELECT_LEX *select_lex)
1491
4111
{
1492
4112
  if ((cmp == &comp_eq_creator) && !all)       //  = ANY <=> IN
1493
4113
    return new Item_in_subselect(left_expr, select_lex);
1505
4125
 
1506
4126
 
1507
4127
/**
1508
 
  Update query pre-check.
 
4128
  Multi update query pre-check.
1509
4129
 
1510
 
  @param session                Thread handler
 
4130
  @param thd            Thread handler
1511
4131
  @param tables Global/local table list (have to be the same)
1512
4132
 
1513
4133
  @retval
1516
4136
    true  Error
1517
4137
*/
1518
4138
 
1519
 
bool update_precheck(Session *session, TableList *)
 
4139
bool multi_update_precheck(THD *thd,
 
4140
                           TABLE_LIST *tables __attribute__((__unused__)))
1520
4141
{
1521
4142
  const char *msg= 0;
1522
 
  Select_Lex *select_lex= &session->getLex()->select_lex;
 
4143
  LEX *lex= thd->lex;
 
4144
  SELECT_LEX *select_lex= &lex->select_lex;
1523
4145
 
1524
 
  if (session->getLex()->select_lex.item_list.elements != session->getLex()->value_list.elements)
 
4146
  if (select_lex->item_list.elements != lex->value_list.elements)
1525
4147
  {
1526
4148
    my_message(ER_WRONG_VALUE_COUNT, ER(ER_WRONG_VALUE_COUNT), MYF(0));
1527
4149
    return(true);
1528
4150
  }
1529
4151
 
1530
 
  if (session->getLex()->select_lex.table_list.elements > 1)
1531
 
  {
1532
 
    if (select_lex->order_list.elements)
1533
 
      msg= "ORDER BY";
1534
 
    else if (select_lex->select_limit)
1535
 
      msg= "LIMIT";
1536
 
    if (msg)
 
4152
  if (select_lex->order_list.elements)
 
4153
    msg= "ORDER BY";
 
4154
  else if (select_lex->select_limit)
 
4155
    msg= "LIMIT";
 
4156
  if (msg)
 
4157
  {
 
4158
    my_error(ER_WRONG_USAGE, MYF(0), "UPDATE", msg);
 
4159
    return(true);
 
4160
  }
 
4161
  return(false);
 
4162
}
 
4163
 
 
4164
/**
 
4165
  Multi delete query pre-check.
 
4166
 
 
4167
  @param thd                    Thread handler
 
4168
  @param tables         Global/local table list
 
4169
 
 
4170
  @retval
 
4171
    false OK
 
4172
  @retval
 
4173
    true  error
 
4174
*/
 
4175
 
 
4176
bool multi_delete_precheck(THD *thd,
 
4177
                           TABLE_LIST *tables __attribute__((__unused__)))
 
4178
{
 
4179
  SELECT_LEX *select_lex= &thd->lex->select_lex;
 
4180
  TABLE_LIST **save_query_tables_own_last= thd->lex->query_tables_own_last;
 
4181
 
 
4182
  thd->lex->query_tables_own_last= 0;
 
4183
  thd->lex->query_tables_own_last= save_query_tables_own_last;
 
4184
 
 
4185
  if ((thd->options & OPTION_SAFE_UPDATES) && !select_lex->where)
 
4186
  {
 
4187
    my_message(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE,
 
4188
               ER(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE), MYF(0));
 
4189
    return(true);
 
4190
  }
 
4191
  return(false);
 
4192
}
 
4193
 
 
4194
 
 
4195
/*
 
4196
  Given a table in the source list, find a correspondent table in the
 
4197
  table references list.
 
4198
 
 
4199
  @param lex Pointer to LEX representing multi-delete.
 
4200
  @param src Source table to match.
 
4201
  @param ref Table references list.
 
4202
 
 
4203
  @remark The source table list (tables listed before the FROM clause
 
4204
  or tables listed in the FROM clause before the USING clause) may
 
4205
  contain table names or aliases that must match unambiguously one,
 
4206
  and only one, table in the target table list (table references list,
 
4207
  after FROM/USING clause).
 
4208
 
 
4209
  @return Matching table, NULL otherwise.
 
4210
*/
 
4211
 
 
4212
static TABLE_LIST *multi_delete_table_match(LEX *lex __attribute__((__unused__)),
 
4213
                                            TABLE_LIST *tbl,
 
4214
                                            TABLE_LIST *tables)
 
4215
{
 
4216
  TABLE_LIST *match= NULL;
 
4217
 
 
4218
  for (TABLE_LIST *elem= tables; elem; elem= elem->next_local)
 
4219
  {
 
4220
    int cmp;
 
4221
 
 
4222
    if (tbl->is_fqtn && elem->is_alias)
 
4223
      continue; /* no match */
 
4224
    if (tbl->is_fqtn && elem->is_fqtn)
 
4225
      cmp= my_strcasecmp(table_alias_charset, tbl->table_name, elem->table_name) ||
 
4226
           strcmp(tbl->db, elem->db);
 
4227
    else if (elem->is_alias)
 
4228
      cmp= my_strcasecmp(table_alias_charset, tbl->alias, elem->alias);
 
4229
    else
 
4230
      cmp= my_strcasecmp(table_alias_charset, tbl->table_name, elem->table_name) ||
 
4231
           strcmp(tbl->db, elem->db);
 
4232
 
 
4233
    if (cmp)
 
4234
      continue;
 
4235
 
 
4236
    if (match)
1537
4237
    {
1538
 
      my_error(ER_WRONG_USAGE, MYF(0), "UPDATE", msg);
 
4238
      my_error(ER_NONUNIQ_TABLE, MYF(0), elem->alias);
 
4239
      return(NULL);
 
4240
    }
 
4241
 
 
4242
    match= elem;
 
4243
  }
 
4244
 
 
4245
  if (!match)
 
4246
    my_error(ER_UNKNOWN_TABLE, MYF(0), tbl->table_name, "MULTI DELETE");
 
4247
 
 
4248
  return(match);
 
4249
}
 
4250
 
 
4251
 
 
4252
/**
 
4253
  Link tables in auxilary table list of multi-delete with corresponding
 
4254
  elements in main table list, and set proper locks for them.
 
4255
 
 
4256
  @param lex   pointer to LEX representing multi-delete
 
4257
 
 
4258
  @retval
 
4259
    false   success
 
4260
  @retval
 
4261
    true    error
 
4262
*/
 
4263
 
 
4264
bool multi_delete_set_locks_and_link_aux_tables(LEX *lex)
 
4265
{
 
4266
  TABLE_LIST *tables= (TABLE_LIST*)lex->select_lex.table_list.first;
 
4267
  TABLE_LIST *target_tbl;
 
4268
 
 
4269
  lex->table_count= 0;
 
4270
 
 
4271
  for (target_tbl= (TABLE_LIST *)lex->auxiliary_table_list.first;
 
4272
       target_tbl; target_tbl= target_tbl->next_local)
 
4273
  {
 
4274
    lex->table_count++;
 
4275
    /* All tables in aux_tables must be found in FROM PART */
 
4276
    TABLE_LIST *walk= multi_delete_table_match(lex, target_tbl, tables);
 
4277
    if (!walk)
1539
4278
      return(true);
 
4279
    if (!walk->derived)
 
4280
    {
 
4281
      target_tbl->table_name= walk->table_name;
 
4282
      target_tbl->table_name_length= walk->table_name_length;
1540
4283
    }
 
4284
    walk->updating= target_tbl->updating;
 
4285
    walk->lock_type= target_tbl->lock_type;
 
4286
    target_tbl->correspondent_table= walk;      // Remember corresponding table
 
4287
  }
 
4288
  return(false);
 
4289
}
 
4290
 
 
4291
 
 
4292
/**
 
4293
  simple UPDATE query pre-check.
 
4294
 
 
4295
  @param thd            Thread handler
 
4296
  @param tables Global table list
 
4297
 
 
4298
  @retval
 
4299
    false OK
 
4300
  @retval
 
4301
    true  Error
 
4302
*/
 
4303
 
 
4304
bool update_precheck(THD *thd, TABLE_LIST *tables __attribute__((__unused__)))
 
4305
{
 
4306
  if (thd->lex->select_lex.item_list.elements != thd->lex->value_list.elements)
 
4307
  {
 
4308
    my_message(ER_WRONG_VALUE_COUNT, ER(ER_WRONG_VALUE_COUNT), MYF(0));
 
4309
    return(true);
1541
4310
  }
1542
4311
  return(false);
1543
4312
}
1546
4315
/**
1547
4316
  simple INSERT query pre-check.
1548
4317
 
1549
 
  @param session                Thread handler
 
4318
  @param thd            Thread handler
1550
4319
  @param tables Global table list
1551
4320
 
1552
4321
  @retval
1555
4324
    true   error
1556
4325
*/
1557
4326
 
1558
 
bool insert_precheck(Session *session, TableList *)
 
4327
bool insert_precheck(THD *thd, TABLE_LIST *tables __attribute__((__unused__)))
1559
4328
{
 
4329
  LEX *lex= thd->lex;
 
4330
 
1560
4331
  /*
1561
4332
    Check that we have modify privileges for the first table and
1562
4333
    select privileges for the rest
1563
4334
  */
1564
 
  if (session->getLex()->update_list.elements != session->getLex()->value_list.elements)
 
4335
  if (lex->update_list.elements != lex->value_list.elements)
1565
4336
  {
1566
4337
    my_message(ER_WRONG_VALUE_COUNT, ER(ER_WRONG_VALUE_COUNT), MYF(0));
1567
4338
    return(true);
1571
4342
 
1572
4343
 
1573
4344
/**
 
4345
  CREATE TABLE query pre-check.
 
4346
 
 
4347
  @param thd                    Thread handler
 
4348
  @param tables         Global table list
 
4349
  @param create_table           Table which will be created
 
4350
 
 
4351
  @retval
 
4352
    false   OK
 
4353
  @retval
 
4354
    true   Error
 
4355
*/
 
4356
 
 
4357
bool create_table_precheck(THD *thd,
 
4358
                           TABLE_LIST *tables __attribute__((__unused__)),
 
4359
                           TABLE_LIST *create_table)
 
4360
{
 
4361
  LEX *lex= thd->lex;
 
4362
  SELECT_LEX *select_lex= &lex->select_lex;
 
4363
  bool error= true;                                 // Error message is given
 
4364
 
 
4365
  if (create_table && (strcmp(create_table->db, "information_schema") == 0))
 
4366
  {
 
4367
    my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), "", "", INFORMATION_SCHEMA_NAME.str);
 
4368
    return(true);
 
4369
  }
 
4370
 
 
4371
  if (select_lex->item_list.elements)
 
4372
  {
 
4373
    /* Check permissions for used tables in CREATE TABLE ... SELECT */
 
4374
 
 
4375
#ifdef NOT_NECESSARY_TO_CHECK_CREATE_TABLE_EXIST_WHEN_PREPARING_STATEMENT
 
4376
    /* This code throws an ill error for CREATE TABLE t1 SELECT * FROM t1 */
 
4377
    /*
 
4378
      Only do the check for PS, because we on execute we have to check that
 
4379
      against the opened tables to ensure we don't use a table that is part
 
4380
      of the view (which can only be done after the table has been opened).
 
4381
    */
 
4382
    if (thd->stmt_arena->is_stmt_prepare_or_first_sp_execute())
 
4383
    {
 
4384
      /*
 
4385
        For temporary tables we don't have to check if the created table exists
 
4386
      */
 
4387
      if (!(lex->create_info.options & HA_LEX_CREATE_TMP_TABLE) &&
 
4388
          find_table_in_global_list(tables, create_table->db,
 
4389
                                    create_table->table_name))
 
4390
      {
 
4391
        error= false;
 
4392
        goto err;
 
4393
      }
 
4394
    }
 
4395
#endif
 
4396
  }
 
4397
  error= false;
 
4398
 
 
4399
  return(error);
 
4400
}
 
4401
 
 
4402
 
 
4403
/**
1574
4404
  negate given expression.
1575
4405
 
1576
 
  @param session  thread handler
 
4406
  @param thd  thread handler
1577
4407
  @param expr expression for negation
1578
4408
 
1579
4409
  @return
1580
4410
    negated expression
1581
4411
*/
1582
4412
 
1583
 
Item *negate_expression(Session *session, Item *expr)
 
4413
Item *negate_expression(THD *thd, Item *expr)
1584
4414
{
1585
4415
  Item *negated;
1586
4416
  if (expr->type() == Item::FUNC_ITEM &&
1588
4418
  {
1589
4419
    /* it is NOT(NOT( ... )) */
1590
4420
    Item *arg= ((Item_func *) expr)->arguments()[0];
1591
 
    enum_parsing_place place= session->getLex()->current_select->parsing_place;
 
4421
    enum_parsing_place place= thd->lex->current_select->parsing_place;
1592
4422
    if (arg->is_bool_func() || place == IN_WHERE || place == IN_HAVING)
1593
4423
      return arg;
1594
4424
    /*
1598
4428
    return new Item_func_ne(arg, new Item_int((char*) "0", 0, 1));
1599
4429
  }
1600
4430
 
1601
 
  if ((negated= expr->neg_transformer(session)) != 0)
 
4431
  if ((negated= expr->neg_transformer(thd)) != 0)
1602
4432
    return negated;
1603
4433
  return new Item_func_not(expr);
1604
4434
}
1605
4435
 
1606
4436
 
 
4437
/**
 
4438
  Check that byte length of a string does not exceed some limit.
 
4439
 
 
4440
  @param str         string to be checked
 
4441
  @param err_msg     error message to be displayed if the string is too long
 
4442
  @param max_length  max length
 
4443
 
 
4444
  @retval
 
4445
    false   the passed string is not longer than max_length
 
4446
  @retval
 
4447
    true    the passed string is longer than max_length
 
4448
 
 
4449
  NOTE
 
4450
    The function is not used in existing code but can be useful later?
 
4451
*/
 
4452
 
 
4453
bool check_string_byte_length(LEX_STRING *str, const char *err_msg,
 
4454
                              uint max_byte_length)
 
4455
{
 
4456
  if (str->length <= max_byte_length)
 
4457
    return false;
 
4458
 
 
4459
  my_error(ER_WRONG_STRING_LENGTH, MYF(0), str->str, err_msg, max_byte_length);
 
4460
 
 
4461
  return true;
 
4462
}
 
4463
 
 
4464
 
1607
4465
/*
1608
4466
  Check that char length of a string does not exceed some limit.
1609
4467
 
1621
4479
 
1622
4480
 
1623
4481
bool check_string_char_length(LEX_STRING *str, const char *err_msg,
1624
 
                              uint32_t max_char_length, const CHARSET_INFO * const cs,
 
4482
                              uint max_char_length, CHARSET_INFO *cs,
1625
4483
                              bool no_error)
1626
4484
{
1627
4485
  int well_formed_error;
1628
 
  uint32_t res= cs->cset->well_formed_len(cs, str->str, str->str + str->length,
 
4486
  uint res= cs->cset->well_formed_len(cs, str->str, str->str + str->length,
1629
4487
                                      max_char_length, &well_formed_error);
1630
4488
 
1631
4489
  if (!well_formed_error &&  str->length == res)
1637
4495
}
1638
4496
 
1639
4497
 
1640
 
bool check_identifier_name(LEX_STRING *str, error_t err_code,
1641
 
                           uint32_t max_char_length,
1642
 
                           const char *param_for_err_msg)
 
4498
bool check_identifier_name(LEX_STRING *str, uint max_char_length,
 
4499
                           uint err_code, const char *param_for_err_msg)
1643
4500
{
 
4501
#ifdef HAVE_CHARSET_utf8mb3
1644
4502
  /*
1645
4503
    We don't support non-BMP characters in identifiers at the moment,
1646
4504
    so they should be prohibited until such support is done.
1647
4505
    This is why we use the 3-byte utf8 to check well-formedness here.
1648
4506
  */
1649
 
  const CHARSET_INFO * const cs= &my_charset_utf8mb4_general_ci;
1650
 
 
 
4507
  CHARSET_INFO *cs= &my_charset_utf8mb3_general_ci;
 
4508
#else
 
4509
  CHARSET_INFO *cs= system_charset_info;
 
4510
#endif
1651
4511
  int well_formed_error;
1652
 
  uint32_t res= cs->cset->well_formed_len(cs, str->str, str->str + str->length,
 
4512
  uint res= cs->cset->well_formed_len(cs, str->str, str->str + str->length,
1653
4513
                                      max_char_length, &well_formed_error);
1654
4514
 
1655
4515
  if (well_formed_error)
1657
4517
    my_error(ER_INVALID_CHARACTER_STRING, MYF(0), "identifier", str->str);
1658
4518
    return true;
1659
4519
  }
1660
 
 
 
4520
  
1661
4521
  if (str->length == res)
1662
4522
    return false;
1663
4523
 
1664
4524
  switch (err_code)
1665
4525
  {
1666
 
  case EE_OK:
 
4526
  case 0:
1667
4527
    break;
1668
4528
  case ER_WRONG_STRING_LENGTH:
1669
4529
    my_error(err_code, MYF(0), str->str, param_for_err_msg, max_char_length);
1675
4535
    assert(0);
1676
4536
    break;
1677
4537
  }
1678
 
 
1679
4538
  return true;
1680
4539
}
1681
4540
 
1682
4541
 
 
4542
/*
 
4543
  Check if path does not contain mysql data home directory
 
4544
  SYNOPSIS
 
4545
    test_if_data_home_dir()
 
4546
    dir                     directory
 
4547
    conv_home_dir           converted data home directory
 
4548
    home_dir_len            converted data home directory length
 
4549
 
 
4550
  RETURN VALUES
 
4551
    0   ok
 
4552
    1   error  
 
4553
*/
 
4554
 
 
4555
bool test_if_data_home_dir(const char *dir)
 
4556
{
 
4557
  char path[FN_REFLEN], conv_path[FN_REFLEN];
 
4558
  uint dir_len, home_dir_len= strlen(mysql_unpacked_real_data_home);
 
4559
 
 
4560
  if (!dir)
 
4561
    return(0);
 
4562
 
 
4563
  (void) fn_format(path, dir, "", "",
 
4564
                   (MY_RETURN_REAL_PATH|MY_RESOLVE_SYMLINKS));
 
4565
  dir_len= unpack_dirname(conv_path, dir);
 
4566
 
 
4567
  if (home_dir_len < dir_len)
 
4568
  {
 
4569
    if (lower_case_file_system)
 
4570
    {
 
4571
      if (!my_strnncoll(character_set_filesystem,
 
4572
                        (const uchar*) conv_path, home_dir_len,
 
4573
                        (const uchar*) mysql_unpacked_real_data_home,
 
4574
                        home_dir_len))
 
4575
        return(1);
 
4576
    }
 
4577
    else if (!memcmp(conv_path, mysql_unpacked_real_data_home, home_dir_len))
 
4578
      return(1);
 
4579
  }
 
4580
  return(0);
 
4581
}
 
4582
 
 
4583
 
 
4584
extern int MYSQLparse(void *thd); // from sql_yacc.cc
 
4585
 
 
4586
 
1683
4587
/**
1684
 
  This is a wrapper of DRIZZLEparse(). All the code should call parse_sql()
1685
 
  instead of DRIZZLEparse().
 
4588
  This is a wrapper of MYSQLparse(). All the code should call parse_sql()
 
4589
  instead of MYSQLparse().
1686
4590
 
1687
 
  @param session Thread context.
 
4591
  @param thd Thread context.
1688
4592
  @param lip Lexer context.
 
4593
  @param creation_ctx Object creation context.
1689
4594
 
1690
4595
  @return Error status.
1691
4596
    @retval false on success.
1692
4597
    @retval true on parsing error.
1693
4598
*/
1694
4599
 
1695
 
static bool parse_sql(Session *session, Lex_input_stream *lip)
 
4600
bool parse_sql(THD *thd,
 
4601
               Lex_input_stream *lip,
 
4602
               Object_creation_ctx *creation_ctx)
1696
4603
{
1697
 
  assert(session->m_lip == NULL);
1698
 
 
1699
 
  DRIZZLE_QUERY_PARSE_START(session->getQueryString()->c_str());
 
4604
  assert(thd->m_lip == NULL);
 
4605
 
 
4606
  /* Backup creation context. */
 
4607
 
 
4608
  Object_creation_ctx *backup_ctx= NULL;
 
4609
 
 
4610
  if (creation_ctx)
 
4611
    backup_ctx= creation_ctx->set_n_backup(thd);
1700
4612
 
1701
4613
  /* Set Lex_input_stream. */
1702
4614
 
1703
 
  session->m_lip= lip;
 
4615
  thd->m_lip= lip;
1704
4616
 
1705
4617
  /* Parse the query. */
1706
4618
 
1707
 
  bool parse_status= base_sql_parse(session) != 0;
1708
 
 
1709
 
  /* Check that if DRIZZLEparse() failed, session->is_error() is set. */
1710
 
 
1711
 
  assert(!parse_status || session->is_error());
 
4619
  bool mysql_parse_status= MYSQLparse(thd) != 0;
 
4620
 
 
4621
  /* Check that if MYSQLparse() failed, thd->is_error() is set. */
 
4622
 
 
4623
  assert(!mysql_parse_status || thd->is_error());
1712
4624
 
1713
4625
  /* Reset Lex_input_stream. */
1714
4626
 
1715
 
  session->m_lip= NULL;
1716
 
 
1717
 
  DRIZZLE_QUERY_PARSE_DONE(parse_status || session->is_fatal_error);
 
4627
  thd->m_lip= NULL;
 
4628
 
 
4629
  /* Restore creation context. */
 
4630
 
 
4631
  if (creation_ctx)
 
4632
    creation_ctx->restore_env(thd, backup_ctx);
1718
4633
 
1719
4634
  /* That's it. */
1720
4635
 
1721
 
  return parse_status || session->is_fatal_error;
 
4636
  return mysql_parse_status || thd->is_fatal_error;
1722
4637
}
1723
4638
 
1724
4639
/**
1725
4640
  @} (end of group Runtime_Environment)
1726
4641
*/
1727
 
 
1728
 
} /* namespace drizzled */