~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_parse.cc

  • Committer: Brian Aker
  • Date: 2009-01-07 21:26:58 UTC
  • Revision ID: brian@tangent.org-20090107212658-2fh0s2uwh10w68y2
Committing fix lock_multi

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"
 
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
17
15
 
18
16
#define DRIZZLE_LEX 1
19
 
 
20
 
#include <drizzled/my_hash.h>
 
17
#include <drizzled/server_includes.h>
 
18
#include <drizzled/replication/replication.h>
 
19
#include <libdrizzle/libdrizzle.h>
 
20
#include <mysys/hash.h>
 
21
#include <drizzled/replication/binlog.h>
 
22
#include <drizzled/logging.h>
 
23
#include <drizzled/db.h>
21
24
#include <drizzled/error.h>
22
25
#include <drizzled/nested_join.h>
23
26
#include <drizzled/query_id.h>
24
 
#include "drizzled/transaction_services.h"
25
27
#include <drizzled/sql_parse.h>
26
28
#include <drizzled/data_home.h>
27
29
#include <drizzled/sql_base.h>
28
30
#include <drizzled/show.h>
29
 
#include <drizzled/db.h>
 
31
#include <drizzled/rename.h>
30
32
#include <drizzled/function/time/unix_timestamp.h>
31
33
#include <drizzled/function/get_system_var.h>
32
34
#include <drizzled/item/cmpfunc.h>
33
35
#include <drizzled/item/null.h>
34
36
#include <drizzled/session.h>
35
37
#include <drizzled/sql_load.h>
 
38
#include <drizzled/connect.h>
36
39
#include <drizzled/lock.h>
37
 
#include <drizzled/select_send.h>
38
 
#include <drizzled/plugin/client.h>
39
 
#include <drizzled/statement.h>
40
 
#include <drizzled/statement/alter_table.h>
41
 
#include "drizzled/probes.h"
42
 
#include "drizzled/session/cache.h"
43
 
#include "drizzled/global_charset_info.h"
44
 
 
45
 
#include "drizzled/plugin/logging.h"
46
 
#include "drizzled/plugin/query_rewrite.h"
47
 
#include "drizzled/plugin/query_cache.h"
48
 
#include "drizzled/plugin/authorization.h"
49
 
#include "drizzled/optimizer/explain_plan.h"
50
 
#include "drizzled/pthread_globals.h"
51
 
#include "drizzled/plugin/event_observer.h"
52
 
 
53
 
#include <limits.h>
54
 
 
55
40
#include <bitset>
56
 
#include <algorithm>
57
 
#include <boost/date_time.hpp>
58
 
#include "drizzled/internal/my_sys.h"
59
41
 
60
42
using namespace std;
61
43
 
62
 
extern int DRIZZLEparse(void *session); // from sql_yacc.cc
63
 
 
64
 
namespace drizzled
65
 
{
66
 
 
67
 
/* Prototypes */
68
 
bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
69
 
static bool parse_sql(Session *session, Lex_input_stream *lip);
70
 
void mysql_parse(Session *session, const char *inBuf, uint32_t length);
71
 
 
72
44
/**
73
45
  @defgroup Runtime_Environment Runtime Environment
74
46
  @{
76
48
 
77
49
extern size_t my_thread_stack_size;
78
50
extern const CHARSET_INFO *character_set_filesystem;
 
51
const char *any_db="*any*";     // Special symbol for check_access
79
52
 
80
53
const LEX_STRING command_name[COM_END+1]={
81
54
  { C_STRING_WITH_LEN("Sleep") },
82
55
  { C_STRING_WITH_LEN("Quit") },
83
56
  { C_STRING_WITH_LEN("Init DB") },
84
57
  { C_STRING_WITH_LEN("Query") },
 
58
  { C_STRING_WITH_LEN("Field List") },
 
59
  { C_STRING_WITH_LEN("Create DB") },
 
60
  { C_STRING_WITH_LEN("Drop DB") },
 
61
  { C_STRING_WITH_LEN("Refresh") },
85
62
  { C_STRING_WITH_LEN("Shutdown") },
 
63
  { C_STRING_WITH_LEN("Processlist") },
86
64
  { C_STRING_WITH_LEN("Connect") },
 
65
  { C_STRING_WITH_LEN("Kill") },
87
66
  { C_STRING_WITH_LEN("Ping") },
 
67
  { C_STRING_WITH_LEN("Time") },
 
68
  { C_STRING_WITH_LEN("Change user") },
 
69
  { C_STRING_WITH_LEN("Binlog Dump") },
 
70
  { C_STRING_WITH_LEN("Connect Out") },
 
71
  { C_STRING_WITH_LEN("Register Slave") },
 
72
  { C_STRING_WITH_LEN("Set option") },
 
73
  { C_STRING_WITH_LEN("Daemon") },
88
74
  { C_STRING_WITH_LEN("Error") }  // Last command number
89
75
};
90
76
 
92
78
  "NON-EXISTING", "ACTIVE", "IDLE", "PREPARED"
93
79
};
94
80
 
 
81
static void unlock_locked_tables(Session *session)
 
82
{
 
83
  if (session->locked_tables)
 
84
  {
 
85
    session->lock=session->locked_tables;
 
86
    session->locked_tables=0;                   // Will be automatically closed
 
87
    close_thread_tables(session);                       // Free tables
 
88
  }
 
89
}
 
90
 
 
91
 
 
92
bool end_active_trans(Session *session)
 
93
{
 
94
  int error= 0;
 
95
 
 
96
  if (session->transaction.xid_state.xa_state != XA_NOTR)
 
97
  {
 
98
    my_error(ER_XAER_RMFAIL, MYF(0),
 
99
             xa_state_names[session->transaction.xid_state.xa_state]);
 
100
    return(1);
 
101
  }
 
102
  if (session->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN |
 
103
                      OPTION_TABLE_LOCK))
 
104
  {
 
105
    /* Safety if one did "drop table" on locked tables */
 
106
    if (!session->locked_tables)
 
107
      session->options&= ~OPTION_TABLE_LOCK;
 
108
    session->server_status&= ~SERVER_STATUS_IN_TRANS;
 
109
    if (ha_commit(session))
 
110
      error=1;
 
111
  }
 
112
  session->options&= ~(OPTION_BEGIN | OPTION_KEEP_LOG);
 
113
  session->transaction.all.modified_non_trans_table= false;
 
114
  return(error);
 
115
}
 
116
 
 
117
 
 
118
bool begin_trans(Session *session)
 
119
{
 
120
  int error= 0;
 
121
  if (session->locked_tables)
 
122
  {
 
123
    session->lock=session->locked_tables;
 
124
    session->locked_tables=0;                   // Will be automatically closed
 
125
    close_thread_tables(session);                       // Free tables
 
126
  }
 
127
  if (end_active_trans(session))
 
128
    error= -1;
 
129
  else
 
130
  {
 
131
    LEX *lex= session->lex;
 
132
    session->options|= OPTION_BEGIN;
 
133
    session->server_status|= SERVER_STATUS_IN_TRANS;
 
134
    if (lex->start_transaction_opt & DRIZZLE_START_TRANS_OPT_WITH_CONS_SNAPSHOT)
 
135
      error= ha_start_consistent_snapshot(session);
 
136
  }
 
137
  return error;
 
138
}
 
139
 
 
140
/**
 
141
  Returns true if all tables should be ignored.
 
142
*/
 
143
inline bool all_tables_not_ok(Session *, TableList *)
 
144
{
 
145
  return false;
 
146
}
 
147
 
95
148
/**
96
149
  Mark all commands that somehow changes a table.
97
150
 
104
157
     2  - query that returns meaningful ROW_COUNT() -
105
158
          a number of modified rows
106
159
*/
 
160
 
107
161
bitset<CF_BIT_SIZE> sql_command_flags[SQLCOM_END+1];
108
162
 
109
163
void init_update_queries(void)
125
179
  sql_command_flags[SQLCOM_DROP_INDEX]=     CF_CHANGES_DATA;
126
180
 
127
181
  sql_command_flags[SQLCOM_UPDATE]=         CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
 
182
  sql_command_flags[SQLCOM_UPDATE_MULTI]=   CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
128
183
  sql_command_flags[SQLCOM_INSERT]=         CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
129
184
  sql_command_flags[SQLCOM_INSERT_SELECT]=  CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
130
185
  sql_command_flags[SQLCOM_DELETE]=         CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
 
186
  sql_command_flags[SQLCOM_DELETE_MULTI]=   CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
131
187
  sql_command_flags[SQLCOM_REPLACE]=        CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
132
188
  sql_command_flags[SQLCOM_REPLACE_SELECT]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
133
189
 
 
190
  sql_command_flags[SQLCOM_SHOW_STATUS]=      CF_STATUS_COMMAND;
 
191
  sql_command_flags[SQLCOM_SHOW_DATABASES]=   CF_STATUS_COMMAND;
 
192
  sql_command_flags[SQLCOM_SHOW_OPEN_TABLES]= CF_STATUS_COMMAND;
 
193
  sql_command_flags[SQLCOM_SHOW_FIELDS]=      CF_STATUS_COMMAND;
 
194
  sql_command_flags[SQLCOM_SHOW_KEYS]=        CF_STATUS_COMMAND;
 
195
  sql_command_flags[SQLCOM_SHOW_VARIABLES]=   CF_STATUS_COMMAND;
 
196
  sql_command_flags[SQLCOM_SHOW_BINLOGS]= CF_STATUS_COMMAND;
134
197
  sql_command_flags[SQLCOM_SHOW_WARNS]= CF_STATUS_COMMAND;
135
198
  sql_command_flags[SQLCOM_SHOW_ERRORS]= CF_STATUS_COMMAND;
 
199
  sql_command_flags[SQLCOM_SHOW_ENGINE_STATUS]= CF_STATUS_COMMAND;
 
200
  sql_command_flags[SQLCOM_SHOW_PROCESSLIST]= CF_STATUS_COMMAND;
136
201
  sql_command_flags[SQLCOM_SHOW_CREATE_DB]=  CF_STATUS_COMMAND;
137
202
  sql_command_flags[SQLCOM_SHOW_CREATE]=  CF_STATUS_COMMAND;
 
203
  sql_command_flags[SQLCOM_SHOW_MASTER_STAT]=  CF_STATUS_COMMAND;
 
204
  sql_command_flags[SQLCOM_SHOW_SLAVE_STAT]=  CF_STATUS_COMMAND;
138
205
 
 
206
   sql_command_flags[SQLCOM_SHOW_TABLES]=       (CF_STATUS_COMMAND |
 
207
                                               CF_SHOW_TABLE_COMMAND);
 
208
  sql_command_flags[SQLCOM_SHOW_TABLE_STATUS]= (CF_STATUS_COMMAND |
 
209
                                                CF_SHOW_TABLE_COMMAND);
139
210
  /*
140
211
    The following admin table operations are allowed
141
212
    on log tables.
142
213
  */
 
214
  sql_command_flags[SQLCOM_REPAIR]=           CF_WRITE_LOGS_COMMAND;
 
215
  sql_command_flags[SQLCOM_OPTIMIZE]=         CF_WRITE_LOGS_COMMAND;
143
216
  sql_command_flags[SQLCOM_ANALYZE]=          CF_WRITE_LOGS_COMMAND;
144
217
}
145
218
 
 
219
 
 
220
bool is_update_query(enum enum_sql_command command)
 
221
{
 
222
  assert(command >= 0 && command <= SQLCOM_END);
 
223
  return (sql_command_flags[command].test(CF_BIT_CHANGES_DATA));
 
224
}
 
225
 
 
226
void execute_init_command(Session *session, sys_var_str *init_command_var,
 
227
                          pthread_rwlock_t *var_mutex)
 
228
{
 
229
  Vio* save_vio;
 
230
  ulong save_client_capabilities;
 
231
 
 
232
  session->set_proc_info("Execution of init_command");
 
233
  /*
 
234
    We need to lock init_command_var because
 
235
    during execution of init_command_var query
 
236
    values of init_command_var can't be changed
 
237
  */
 
238
  pthread_rwlock_rdlock(var_mutex);
 
239
  save_client_capabilities= session->client_capabilities;
 
240
  session->client_capabilities|= CLIENT_MULTI_STATEMENTS;
 
241
  /*
 
242
    We don't need return result of execution to client side.
 
243
    To forbid this we should set session->net.vio to 0.
 
244
  */
 
245
  save_vio= session->net.vio;
 
246
  session->net.vio= 0;
 
247
  dispatch_command(COM_QUERY, session,
 
248
                   init_command_var->value,
 
249
                   init_command_var->value_length);
 
250
  pthread_rwlock_unlock(var_mutex);
 
251
  session->client_capabilities= save_client_capabilities;
 
252
  session->net.vio= save_vio;
 
253
}
 
254
 
 
255
/**
 
256
  Ends the current transaction and (maybe) begin the next.
 
257
 
 
258
  @param session            Current thread
 
259
  @param completion     Completion type
 
260
 
 
261
  @retval
 
262
    0   OK
 
263
*/
 
264
 
 
265
int end_trans(Session *session, enum enum_mysql_completiontype completion)
 
266
{
 
267
  bool do_release= 0;
 
268
  int res= 0;
 
269
 
 
270
  if (session->transaction.xid_state.xa_state != XA_NOTR)
 
271
  {
 
272
    my_error(ER_XAER_RMFAIL, MYF(0),
 
273
             xa_state_names[session->transaction.xid_state.xa_state]);
 
274
    return(1);
 
275
  }
 
276
  switch (completion) {
 
277
  case COMMIT:
 
278
    /*
 
279
     We don't use end_active_trans() here to ensure that this works
 
280
     even if there is a problem with the OPTION_AUTO_COMMIT flag
 
281
     (Which of course should never happen...)
 
282
    */
 
283
    session->server_status&= ~SERVER_STATUS_IN_TRANS;
 
284
    res= ha_commit(session);
 
285
    session->options&= ~(OPTION_BEGIN | OPTION_KEEP_LOG);
 
286
    session->transaction.all.modified_non_trans_table= false;
 
287
    break;
 
288
  case COMMIT_RELEASE:
 
289
    do_release= 1; /* fall through */
 
290
  case COMMIT_AND_CHAIN:
 
291
    res= end_active_trans(session);
 
292
    if (!res && completion == COMMIT_AND_CHAIN)
 
293
      res= begin_trans(session);
 
294
    break;
 
295
  case ROLLBACK_RELEASE:
 
296
    do_release= 1; /* fall through */
 
297
  case ROLLBACK:
 
298
  case ROLLBACK_AND_CHAIN:
 
299
  {
 
300
    session->server_status&= ~SERVER_STATUS_IN_TRANS;
 
301
    if (ha_rollback(session))
 
302
      res= -1;
 
303
    session->options&= ~(OPTION_BEGIN | OPTION_KEEP_LOG);
 
304
    session->transaction.all.modified_non_trans_table= false;
 
305
    if (!res && (completion == ROLLBACK_AND_CHAIN))
 
306
      res= begin_trans(session);
 
307
    break;
 
308
  }
 
309
  default:
 
310
    res= -1;
 
311
    my_error(ER_UNKNOWN_COM_ERROR, MYF(0));
 
312
    return(-1);
 
313
  }
 
314
 
 
315
  if (res < 0)
 
316
    my_error(session->killed_errno(), MYF(0));
 
317
  else if ((res == 0) && do_release)
 
318
    session->killed= Session::KILL_CONNECTION;
 
319
 
 
320
  return(res);
 
321
}
 
322
 
 
323
 
 
324
/**
 
325
  Read one command from connection and execute it (query or simple command).
 
326
  This function is called in loop from thread function.
 
327
 
 
328
  For profiling to work, it must never be called recursively.
 
329
 
 
330
  @retval
 
331
    0  success
 
332
  @retval
 
333
    1  request of thread shutdown (see dispatch_command() description)
 
334
*/
 
335
 
 
336
bool do_command(Session *session)
 
337
{
 
338
  bool return_value;
 
339
  char *packet= 0;
 
340
  ulong packet_length;
 
341
  NET *net= &session->net;
 
342
  enum enum_server_command command;
 
343
 
 
344
  /*
 
345
    indicator of uninitialized lex => normal flow of errors handling
 
346
    (see my_message_sql)
 
347
  */
 
348
  session->lex->current_select= 0;
 
349
 
 
350
  /*
 
351
    This thread will do a blocking read from the client which
 
352
    will be interrupted when the next command is received from
 
353
    the client, the connection is closed or "net_wait_timeout"
 
354
    number of seconds has passed
 
355
  */
 
356
  my_net_set_read_timeout(net, session->variables.net_wait_timeout);
 
357
 
 
358
  /*
 
359
    XXX: this code is here only to clear possible errors of init_connect.
 
360
    Consider moving to init_connect() instead.
 
361
  */
 
362
  session->clear_error();                               // Clear error message
 
363
  session->main_da.reset_diagnostics_area();
 
364
 
 
365
  net_new_transaction(net);
 
366
 
 
367
  packet_length= my_net_read(net);
 
368
  if (packet_length == packet_error)
 
369
  {
 
370
    /* Check if we can continue without closing the connection */
 
371
 
 
372
    /* The error must be set. */
 
373
    /* This assert is killing me - and tracking down why the error isn't
 
374
     * set here is a waste since the protocol lib is being replaced. */ 
 
375
    //assert(session->is_error());
 
376
    net_end_statement(session);
 
377
 
 
378
    if (net->error != 3)
 
379
    {
 
380
      return_value= true;                       // We have to close it.
 
381
      goto out;
 
382
    }
 
383
 
 
384
    net->error= 0;
 
385
    return_value= false;
 
386
    goto out;
 
387
  }
 
388
 
 
389
  packet= (char*) net->read_pos;
 
390
  /*
 
391
    'packet_length' contains length of data, as it was stored in packet
 
392
    header. In case of malformed header, my_net_read returns zero.
 
393
    If packet_length is not zero, my_net_read ensures that the returned
 
394
    number of bytes was actually read from network.
 
395
    There is also an extra safety measure in my_net_read:
 
396
    it sets packet[packet_length]= 0, but only for non-zero packets.
 
397
  */
 
398
  if (packet_length == 0)                       /* safety */
 
399
  {
 
400
    /* Initialize with COM_SLEEP packet */
 
401
    packet[0]= (unsigned char) COM_SLEEP;
 
402
    packet_length= 1;
 
403
  }
 
404
  /* Do not rely on my_net_read, extra safety against programming errors. */
 
405
  packet[packet_length]= '\0';                  /* safety */
 
406
 
 
407
  command= (enum enum_server_command) (unsigned char) packet[0];
 
408
 
 
409
  if (command >= COM_END)
 
410
    command= COM_END;                           // Wrong command
 
411
 
 
412
  /* Restore read timeout value */
 
413
  my_net_set_read_timeout(net, session->variables.net_read_timeout);
 
414
 
 
415
  assert(packet_length);
 
416
  return_value= dispatch_command(command, session, packet+1, (uint32_t) (packet_length-1));
 
417
 
 
418
out:
 
419
  return(return_value);
 
420
}
 
421
 
146
422
/**
147
423
  Perform one connection-level (COM_XXXX) command.
148
424
 
167
443
bool dispatch_command(enum enum_server_command command, Session *session,
168
444
                      char* packet, uint32_t packet_length)
169
445
{
 
446
  NET *net= &session->net;
170
447
  bool error= 0;
171
448
  Query_id &query_id= Query_id::get_query_id();
172
449
 
173
 
  DRIZZLE_COMMAND_START(session->thread_id, command);
174
 
 
175
 
  session->command= command;
 
450
  session->command=command;
176
451
  session->lex->sql_command= SQLCOM_END; /* to avoid confusing VIEW detectors */
177
452
  session->set_time();
178
 
  session->setQueryId(query_id.value());
 
453
  pthread_mutex_lock(&LOCK_thread_count);
 
454
  session->query_id= query_id.value();
179
455
 
180
456
  switch( command ) {
181
457
  /* Ignore these statements. */
183
459
    break;
184
460
  /* Increase id and count all other statements. */
185
461
  default:
186
 
    session->status_var.questions++;
 
462
    statistic_increment(session->status_var.questions, &LOCK_status);
187
463
    query_id.next();
188
464
  }
189
465
 
 
466
  thread_running++;
190
467
  /* TODO: set session->lex->sql_command to SQLCOM_END here */
 
468
  pthread_mutex_unlock(&LOCK_thread_count);
191
469
 
192
 
  plugin::Logging::preDo(session);
193
 
  if (unlikely(plugin::EventObserver::beforeStatement(*session)))
194
 
  {
195
 
    // We should do something about an error...
196
 
  }
 
470
  logging_pre_do(session);
197
471
 
198
472
  session->server_status&=
199
473
           ~(SERVER_QUERY_NO_INDEX_USED | SERVER_QUERY_NO_GOOD_INDEX_USED);
200
474
  switch (command) {
201
475
  case COM_INIT_DB:
202
476
  {
203
 
    if (packet_length == 0)
204
 
    {
205
 
      my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
206
 
      break;
207
 
    }
208
 
 
209
 
    string tmp(packet, packet_length);
210
 
 
211
 
    SchemaIdentifier identifier(tmp);
212
 
 
213
 
    if (not mysql_change_db(session, identifier))
214
 
    {
215
 
      session->my_ok();
 
477
    LEX_STRING tmp;
 
478
    status_var_increment(session->status_var.com_stat[SQLCOM_CHANGE_DB]);
 
479
    session->convert_string(&tmp, system_charset_info,
 
480
                        packet, packet_length, session->charset());
 
481
    if (!mysql_change_db(session, &tmp, false))
 
482
    {
 
483
      my_ok(session);
 
484
    }
 
485
    break;
 
486
  }
 
487
  case COM_CHANGE_USER:
 
488
  {
 
489
    status_var_increment(session->status_var.com_other);
 
490
    char *user= (char*) packet, *packet_end= packet + packet_length;
 
491
    /* Safe because there is always a trailing \0 at the end of the packet */
 
492
    char *passwd= strchr(user, '\0')+1;
 
493
 
 
494
 
 
495
    session->clear_error();                         // if errors from rollback
 
496
 
 
497
    /*
 
498
      Old clients send null-terminated string ('\0' for empty string) for
 
499
      password.  New clients send the size (1 byte) + string (not null
 
500
      terminated, so also '\0' for empty string).
 
501
 
 
502
      Cast *passwd to an unsigned char, so that it doesn't extend the sign
 
503
      for *passwd > 127 and become 2**32-127 after casting to uint32_t.
 
504
    */
 
505
    char db_buff[NAME_LEN+1];                 // buffer to store db in utf8
 
506
    char *db= passwd;
 
507
    char *save_db;
 
508
    /*
 
509
      If there is no password supplied, the packet must contain '\0',
 
510
      in any type of handshake (4.1 or pre-4.1).
 
511
     */
 
512
    if (passwd >= packet_end)
 
513
    {
 
514
      my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
 
515
      break;
 
516
    }
 
517
    uint32_t passwd_len= (session->client_capabilities & CLIENT_SECURE_CONNECTION ?
 
518
                      (unsigned char)(*passwd++) : strlen(passwd));
 
519
    uint32_t dummy_errors, save_db_length, db_length;
 
520
    int res;
 
521
    USER_CONN *save_user_connect;
 
522
    string old_username;
 
523
 
 
524
    db+= passwd_len + 1;
 
525
    /*
 
526
      Database name is always NUL-terminated, so in case of empty database
 
527
      the packet must contain at least the trailing '\0'.
 
528
    */
 
529
    if (db >= packet_end)
 
530
    {
 
531
      my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
 
532
      break;
 
533
    }
 
534
    db_length= strlen(db);
 
535
 
 
536
    char *ptr= db + db_length + 1;
 
537
    uint32_t cs_number= 0;
 
538
 
 
539
    if (ptr < packet_end)
 
540
    {
 
541
      if (ptr + 2 > packet_end)
 
542
      {
 
543
        my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
 
544
        break;
 
545
      }
 
546
 
 
547
      cs_number= uint2korr(ptr);
 
548
    }
 
549
 
 
550
    /* Convert database name to utf8 */
 
551
    db_buff[copy_and_convert(db_buff, sizeof(db_buff)-1,
 
552
                             system_charset_info, db, db_length,
 
553
                             session->charset(), &dummy_errors)]= 0;
 
554
    db= db_buff;
 
555
 
 
556
    /* Save user and privileges */
 
557
    save_db_length= session->db_length;
 
558
    save_db= session->db;
 
559
    save_user_connect= session->user_connect;
 
560
 
 
561
    old_username= session->security_ctx.user;
 
562
    session->security_ctx.user.assign(user);
 
563
 
 
564
    /* Clear variables that are allocated */
 
565
    session->user_connect= 0;
 
566
    res= check_user(session, passwd, passwd_len, db, false);
 
567
 
 
568
    if (res)
 
569
    {
 
570
      session->security_ctx.user= old_username;
 
571
      session->user_connect= save_user_connect;
 
572
      session->db= save_db;
 
573
      session->db_length= save_db_length;
 
574
    }
 
575
    else
 
576
    {
 
577
      if (save_db)
 
578
        free(save_db);
 
579
 
 
580
      if (cs_number)
 
581
      {
 
582
        session->update_charset();
 
583
      }
216
584
    }
217
585
    break;
218
586
  }
219
587
  case COM_QUERY:
220
588
  {
221
 
    if (not session->readAndStoreQuery(packet, packet_length))
 
589
    if (alloc_query(session, packet, packet_length))
222
590
      break;                                    // fatal error is set
223
 
    DRIZZLE_QUERY_START(session->getQueryString()->c_str(),
224
 
                        session->thread_id,
225
 
                        const_cast<const char *>(session->schema()->c_str()));
226
 
 
227
 
    mysql_parse(session, session->getQueryString()->c_str(), session->getQueryString()->length());
228
 
 
 
591
    char *packet_end= session->query + session->query_length;
 
592
    const char* end_of_stmt= NULL;
 
593
 
 
594
    mysql_parse(session, session->query, session->query_length, &end_of_stmt);
 
595
 
 
596
    while (!session->killed && (end_of_stmt != NULL) && ! session->is_error())
 
597
    {
 
598
      char *beginning_of_next_stmt= (char*) end_of_stmt;
 
599
 
 
600
      net_end_statement(session);
 
601
      /*
 
602
        Multiple queries exits, execute them individually
 
603
      */
 
604
      close_thread_tables(session);
 
605
      ulong length= (ulong)(packet_end - beginning_of_next_stmt);
 
606
 
 
607
      log_slow_statement(session);
 
608
 
 
609
      /* Remove garbage at start of query */
 
610
      while (length > 0 && my_isspace(session->charset(), *beginning_of_next_stmt))
 
611
      {
 
612
        beginning_of_next_stmt++;
 
613
        length--;
 
614
      }
 
615
 
 
616
      pthread_mutex_lock(&LOCK_thread_count);
 
617
      session->query_length= length;
 
618
      session->query= beginning_of_next_stmt;
 
619
      /*
 
620
        Count each statement from the client.
 
621
      */
 
622
      statistic_increment(session->status_var.questions, &LOCK_status);
 
623
      session->query_id= query_id.next();
 
624
      session->set_time(); /* Reset the query start time. */
 
625
      /* TODO: set session->lex->sql_command to SQLCOM_END here */
 
626
      pthread_mutex_unlock(&LOCK_thread_count);
 
627
 
 
628
      mysql_parse(session, beginning_of_next_stmt, length, &end_of_stmt);
 
629
    }
 
630
    break;
 
631
  }
 
632
  case COM_FIELD_LIST:                          // This isn't actually needed
 
633
  {
 
634
    char *fields, *packet_end= packet + packet_length, *arg_end;
 
635
    /* Locked closure of all tables */
 
636
    TableList table_list;
 
637
    LEX_STRING conv_name;
 
638
 
 
639
    /* used as fields initializator */
 
640
    lex_start(session);
 
641
 
 
642
    status_var_increment(session->status_var.com_stat[SQLCOM_SHOW_FIELDS]);
 
643
    memset(&table_list, 0, sizeof(table_list));
 
644
    if (session->copy_db_to(&table_list.db, &table_list.db_length))
 
645
      break;
 
646
    /*
 
647
      We have name + wildcard in packet, separated by endzero
 
648
    */
 
649
    arg_end= strchr(packet, '\0');
 
650
    session->convert_string(&conv_name, system_charset_info,
 
651
                        packet, (uint32_t) (arg_end - packet), session->charset());
 
652
    table_list.alias= table_list.table_name= conv_name.str;
 
653
    packet= arg_end + 1;
 
654
 
 
655
    if (!my_strcasecmp(system_charset_info, table_list.db,
 
656
                       INFORMATION_SCHEMA_NAME.c_str()))
 
657
    {
 
658
      ST_SCHEMA_TABLE *schema_table= find_schema_table(session, table_list.alias);
 
659
      if (schema_table)
 
660
        table_list.schema_table= schema_table;
 
661
    }
 
662
 
 
663
    session->query_length= (uint32_t) (packet_end - packet); // Don't count end \0
 
664
    if (!(session->query=fields= (char*) session->memdup(packet,session->query_length+1)))
 
665
      break;
 
666
    if (lower_case_table_names)
 
667
      my_casedn_str(files_charset_info, table_list.table_name);
 
668
 
 
669
    /* init structures for VIEW processing */
 
670
    table_list.select_lex= &(session->lex->select_lex);
 
671
 
 
672
    lex_start(session);
 
673
    session->reset_for_next_command();
 
674
 
 
675
    session->lex->
 
676
      select_lex.table_list.link_in_list((unsigned char*) &table_list,
 
677
                                         (unsigned char**) &table_list.next_local);
 
678
    session->lex->add_to_query_tables(&table_list);
 
679
 
 
680
    /* switch on VIEW optimisation: do not fill temporary tables */
 
681
    session->lex->sql_command= SQLCOM_SHOW_FIELDS;
 
682
    mysqld_list_fields(session,&table_list,fields);
 
683
    session->lex->unit.cleanup();
 
684
    session->cleanup_after_query();
229
685
    break;
230
686
  }
231
687
  case COM_QUIT:
232
688
    /* We don't calculate statistics for this command */
 
689
    net->error=0;                               // Don't give 'abort' message
233
690
    session->main_da.disable_status();              // Don't send anything back
234
691
    error=true;                                 // End server
235
692
    break;
 
693
  case COM_BINLOG_DUMP:
 
694
    {
 
695
      ulong pos;
 
696
      uint16_t flags;
 
697
      uint32_t slave_server_id;
 
698
 
 
699
      status_var_increment(session->status_var.com_other);
 
700
      /* TODO: The following has to be changed to an 8 byte integer */
 
701
      pos = uint4korr(packet);
 
702
      flags = uint2korr(packet + 4);
 
703
      session->server_id=0; /* avoid suicide */
 
704
      if ((slave_server_id= uint4korr(packet+6))) // mysqlbinlog.server_id==0
 
705
        kill_zombie_dump_threads(slave_server_id);
 
706
      session->server_id = slave_server_id;
 
707
 
 
708
      mysql_binlog_send(session, session->strdup(packet + 10), (my_off_t) pos, flags);
 
709
      /*  fake COM_QUIT -- if we get here, the thread needs to terminate */
 
710
      error = true;
 
711
      break;
 
712
    }
236
713
  case COM_SHUTDOWN:
237
714
  {
238
 
    session->status_var.com_other++;
239
 
    session->my_eof();
240
 
    session->close_thread_tables();                     // Free before kill
 
715
    status_var_increment(session->status_var.com_other);
 
716
    my_eof(session);
 
717
    close_thread_tables(session);                       // Free before kill
241
718
    kill_drizzle();
242
719
    error=true;
243
720
    break;
244
721
  }
245
722
  case COM_PING:
246
 
    session->status_var.com_other++;
247
 
    session->my_ok();                           // Tell client we are alive
248
 
    break;
 
723
    status_var_increment(session->status_var.com_other);
 
724
    my_ok(session);                             // Tell client we are alive
 
725
    break;
 
726
  case COM_PROCESS_INFO:
 
727
    status_var_increment(session->status_var.com_stat[SQLCOM_SHOW_PROCESSLIST]);
 
728
    mysqld_list_processes(session, NULL, 0);
 
729
    break;
 
730
  case COM_PROCESS_KILL:
 
731
  {
 
732
    status_var_increment(session->status_var.com_stat[SQLCOM_KILL]);
 
733
    ulong id=(ulong) uint4korr(packet);
 
734
    sql_kill(session,id,false);
 
735
    break;
 
736
  }
 
737
  case COM_SET_OPTION:
 
738
  {
 
739
    status_var_increment(session->status_var.com_stat[SQLCOM_SET_OPTION]);
 
740
    uint32_t opt_command= uint2korr(packet);
 
741
 
 
742
    switch (opt_command) {
 
743
    case (int) DRIZZLE_OPTION_MULTI_STATEMENTS_ON:
 
744
      session->client_capabilities|= CLIENT_MULTI_STATEMENTS;
 
745
      my_eof(session);
 
746
      break;
 
747
    case (int) DRIZZLE_OPTION_MULTI_STATEMENTS_OFF:
 
748
      session->client_capabilities&= ~CLIENT_MULTI_STATEMENTS;
 
749
      my_eof(session);
 
750
      break;
 
751
    default:
 
752
      my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
 
753
      break;
 
754
    }
 
755
    break;
 
756
  }
249
757
  case COM_SLEEP:
250
758
  case COM_CONNECT:                             // Impossible here
 
759
  case COM_TIME:                                // Impossible from client
251
760
  case COM_END:
252
761
  default:
253
762
    my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
256
765
 
257
766
  /* If commit fails, we should be able to reset the OK status. */
258
767
  session->main_da.can_overwrite_status= true;
259
 
  TransactionServices &transaction_services= TransactionServices::singleton();
260
 
  transaction_services.autocommitOrRollback(session, session->is_error());
 
768
  ha_autocommit_or_rollback(session, session->is_error());
261
769
  session->main_da.can_overwrite_status= false;
262
770
 
263
771
  session->transaction.stmt.reset();
269
777
    if (! session->main_da.is_set())
270
778
      session->send_kill_message();
271
779
  }
272
 
  if (session->getKilled() == Session::KILL_QUERY || session->getKilled() == Session::KILL_BAD_DATA)
273
 
  {
274
 
    session->setKilled(Session::NOT_KILLED);
275
 
    session->setAbort(false);
276
 
  }
277
 
 
278
 
  /* Can not be true, but do not take chances in production. */
279
 
  assert(! session->main_da.is_sent);
280
 
 
281
 
  switch (session->main_da.status())
282
 
  {
283
 
  case Diagnostics_area::DA_ERROR:
284
 
    /* The query failed, send error to log and abort bootstrap. */
285
 
    session->client->sendError(session->main_da.sql_errno(),
286
 
                               session->main_da.message());
287
 
    break;
288
 
 
289
 
  case Diagnostics_area::DA_EOF:
290
 
    session->client->sendEOF();
291
 
    break;
292
 
 
293
 
  case Diagnostics_area::DA_OK:
294
 
    session->client->sendOK();
295
 
    break;
296
 
 
297
 
  case Diagnostics_area::DA_DISABLED:
298
 
    break;
299
 
 
300
 
  case Diagnostics_area::DA_EMPTY:
301
 
  default:
302
 
    session->client->sendOK();
303
 
    break;
304
 
  }
305
 
 
306
 
  session->main_da.is_sent= true;
 
780
  if (session->killed == Session::KILL_QUERY || session->killed == Session::KILL_BAD_DATA)
 
781
  {
 
782
    session->killed= Session::NOT_KILLED;
 
783
    session->mysys_var->abort= 0;
 
784
  }
 
785
 
 
786
  net_end_statement(session);
307
787
 
308
788
  session->set_proc_info("closing tables");
309
789
  /* Free tables */
310
 
  session->close_thread_tables();
311
 
 
312
 
  plugin::Logging::postDo(session);
313
 
  if (unlikely(plugin::EventObserver::afterStatement(*session)))
314
 
  {
315
 
    // We should do something about an error...
316
 
  }
317
 
 
318
 
  /* Store temp state for processlist */
 
790
  close_thread_tables(session);
 
791
 
 
792
  log_slow_statement(session);
 
793
 
319
794
  session->set_proc_info("cleaning up");
320
 
  session->command= COM_SLEEP;
321
 
  session->resetQueryString();
322
 
 
323
 
  session->set_proc_info(NULL);
324
 
  session->mem_root->free_root(MYF(memory::KEEP_PREALLOC));
325
 
 
326
 
  if (DRIZZLE_QUERY_DONE_ENABLED() || DRIZZLE_COMMAND_DONE_ENABLED())
327
 
  {
328
 
    if (command == COM_QUERY)
329
 
    {
330
 
      DRIZZLE_QUERY_DONE(session->is_error());
331
 
    }
332
 
    DRIZZLE_COMMAND_DONE(session->is_error());
333
 
  }
334
 
 
335
 
  return error;
 
795
  pthread_mutex_lock(&LOCK_thread_count); // For process list
 
796
  session->set_proc_info(0);
 
797
  session->command=COM_SLEEP;
 
798
  session->query=0;
 
799
  session->query_length=0;
 
800
  thread_running--;
 
801
  pthread_mutex_unlock(&LOCK_thread_count);
 
802
  session->packet.shrink(session->variables.net_buffer_length); // Reclaim some memory
 
803
  free_root(session->mem_root,MYF(MY_KEEP_PREALLOC));
 
804
  return(error);
 
805
}
 
806
 
 
807
 
 
808
void log_slow_statement(Session *session)
 
809
{
 
810
  logging_post_do(session);
 
811
 
 
812
  return;
336
813
}
337
814
 
338
815
 
341
818
 
342
819
    This function is used in the parser to convert a SHOW or DESCRIBE
343
820
    table_name command to a SELECT from INFORMATION_SCHEMA.
344
 
    It prepares a Select_Lex and a TableList object to represent the
 
821
    It prepares a SELECT_LEX and a TableList object to represent the
345
822
    given command as a SELECT parse tree.
346
823
 
347
 
  @param session           thread handle
348
 
  @param lex               current lex
349
 
  @param table_ident       table alias if it's used
350
 
  @param schema_table_name the name of the INFORMATION_SCHEMA table to be
351
 
                           created
 
824
  @param session              thread handle
 
825
  @param lex              current lex
 
826
  @param table_ident      table alias if it's used
 
827
  @param schema_table_idx the type of the INFORMATION_SCHEMA table to be
 
828
                          created
352
829
 
353
830
  @note
354
831
    Due to the way this function works with memory and LEX it cannot
361
838
    1                 out of memory or SHOW commands are not allowed
362
839
                      in this version of the server.
363
840
*/
364
 
static bool _schema_select(Session *session, Select_Lex *sel,
365
 
                           const string& schema_table_name)
 
841
 
 
842
int prepare_schema_table(Session *session, LEX *lex, Table_ident *table_ident,
 
843
                         enum enum_schema_tables schema_table_idx)
366
844
{
367
 
  LEX_STRING db, table;
368
 
  bitset<NUM_OF_TABLE_OPTIONS> table_options;
369
 
  /*
370
 
     We have to make non const db_name & table_name
371
 
     because of lower_case_table_names
372
 
  */
373
 
  session->make_lex_string(&db, "data_dictionary", sizeof("data_dictionary"), false);
374
 
  session->make_lex_string(&table, schema_table_name, false);
375
 
 
376
 
  if (! sel->add_table_to_list(session, new Table_ident(db, table),
377
 
                               NULL, table_options, TL_READ))
 
845
  SELECT_LEX *schema_select_lex= NULL;
 
846
 
 
847
  switch (schema_table_idx) {
 
848
  case SCH_SCHEMATA:
 
849
    break;
 
850
  case SCH_TABLE_NAMES:
 
851
  case SCH_TABLES:
 
852
    {
 
853
      LEX_STRING db;
 
854
      size_t dummy;
 
855
      if (lex->select_lex.db == NULL &&
 
856
          lex->copy_db_to(&lex->select_lex.db, &dummy))
 
857
      {
 
858
        return(1);
 
859
      }
 
860
      schema_select_lex= new SELECT_LEX();
 
861
      db.str= schema_select_lex->db= lex->select_lex.db;
 
862
      schema_select_lex->table_list.first= NULL;
 
863
      db.length= strlen(db.str);
 
864
 
 
865
      if (check_db_name(&db))
 
866
      {
 
867
        my_error(ER_WRONG_DB_NAME, MYF(0), db.str);
 
868
        return(1);
 
869
      }
 
870
      break;
 
871
    }
 
872
  case SCH_COLUMNS:
 
873
  case SCH_STATISTICS:
378
874
  {
379
 
    return true;
380
 
  }
381
 
  return false;
382
 
}
383
 
 
384
 
int prepare_new_schema_table(Session *session, LEX *lex,
385
 
                             const string& schema_table_name)
386
 
{
387
 
  Select_Lex *schema_select_lex= NULL;
388
 
 
389
 
  Select_Lex *select_lex= lex->current_select;
 
875
    assert(table_ident);
 
876
    TableList **query_tables_last= lex->query_tables_last;
 
877
    schema_select_lex= new SELECT_LEX();
 
878
    /* 'parent_lex' is used in init_query() so it must be before it. */
 
879
    schema_select_lex->parent_lex= lex;
 
880
    schema_select_lex->init_query();
 
881
    if (!schema_select_lex->add_table_to_list(session, table_ident, 0, 0, TL_READ))
 
882
      return(1);
 
883
    lex->query_tables_last= query_tables_last;
 
884
    break;
 
885
  }
 
886
  case SCH_OPEN_TABLES:
 
887
  case SCH_VARIABLES:
 
888
  case SCH_STATUS:
 
889
  case SCH_CHARSETS:
 
890
  case SCH_COLLATIONS:
 
891
  case SCH_COLLATION_CHARACTER_SET_APPLICABILITY:
 
892
  case SCH_TABLE_CONSTRAINTS:
 
893
  case SCH_KEY_COLUMN_USAGE:
 
894
  default:
 
895
    break;
 
896
  }
 
897
 
 
898
  SELECT_LEX *select_lex= lex->current_select;
390
899
  assert(select_lex);
391
 
  if (_schema_select(session, select_lex, schema_table_name))
 
900
  if (make_schema_select(session, select_lex, schema_table_idx))
392
901
  {
393
902
    return(1);
394
903
  }
395
904
  TableList *table_list= (TableList*) select_lex->table_list.first;
396
905
  assert(table_list);
397
906
  table_list->schema_select_lex= schema_select_lex;
398
 
 
399
 
  return 0;
 
907
  table_list->schema_table_reformed= 1;
 
908
  return(0);
 
909
}
 
910
 
 
911
 
 
912
/**
 
913
  Read query from packet and store in session->query.
 
914
  Used in COM_QUERY and COM_STMT_PREPARE.
 
915
 
 
916
    Sets the following Session variables:
 
917
  - query
 
918
  - query_length
 
919
 
 
920
  @retval
 
921
    false ok
 
922
  @retval
 
923
    true  error;  In this case session->fatal_error is set
 
924
*/
 
925
 
 
926
bool alloc_query(Session *session, const char *packet, uint32_t packet_length)
 
927
{
 
928
  /* Remove garbage at start and end of query */
 
929
  while (packet_length > 0 && my_isspace(session->charset(), packet[0]))
 
930
  {
 
931
    packet++;
 
932
    packet_length--;
 
933
  }
 
934
  const char *pos= packet + packet_length;     // Point at end null
 
935
  while (packet_length > 0 &&
 
936
         (pos[-1] == ';' || my_isspace(session->charset() ,pos[-1])))
 
937
  {
 
938
    pos--;
 
939
    packet_length--;
 
940
  }
 
941
  /* We must allocate some extra memory for query cache */
 
942
  session->query_length= 0;                        // Extra safety: Avoid races
 
943
  if (!(session->query= (char*) session->memdup_w_gap((unsigned char*) (packet),
 
944
                                              packet_length,
 
945
                                              session->db_length+ 1)))
 
946
    return true;
 
947
  session->query[packet_length]=0;
 
948
  session->query_length= packet_length;
 
949
 
 
950
  /* Reclaim some memory */
 
951
  session->packet.shrink(session->variables.net_buffer_length);
 
952
  session->convert_buffer.shrink(session->variables.net_buffer_length);
 
953
 
 
954
  return false;
400
955
}
401
956
 
402
957
/**
429
984
    true        Error
430
985
*/
431
986
 
432
 
static int mysql_execute_command(Session *session)
 
987
int
 
988
mysql_execute_command(Session *session)
433
989
{
434
 
  bool res= false;
 
990
  int res= false;
 
991
  bool need_start_waiting= false; // have protection against global read lock
 
992
  int  up_result= 0;
435
993
  LEX  *lex= session->lex;
436
 
  /* first Select_Lex (have special meaning for many of non-SELECTcommands) */
437
 
  Select_Lex *select_lex= &lex->select_lex;
 
994
  /* first SELECT_LEX (have special meaning for many of non-SELECTcommands) */
 
995
  SELECT_LEX *select_lex= &lex->select_lex;
 
996
  /* first table of first SELECT_LEX */
 
997
  TableList *first_table= (TableList*) select_lex->table_list.first;
438
998
  /* list of all tables in query */
439
999
  TableList *all_tables;
 
1000
  /* most outer SELECT_LEX_UNIT of query */
 
1001
  SELECT_LEX_UNIT *unit= &lex->unit;
 
1002
  /* Saved variable value */
440
1003
 
441
1004
  /*
442
 
    In many cases first table of main Select_Lex have special meaning =>
 
1005
    In many cases first table of main SELECT_LEX have special meaning =>
443
1006
    check that it is first table in global list and relink it first in
444
1007
    queries_tables list if it is necessary (we need such relinking only
445
1008
    for queries with subqueries in select list, in this case tables of
446
1009
    subqueries will go to global list first)
447
1010
 
448
 
    all_tables will differ from first_table only if most upper Select_Lex
 
1011
    all_tables will differ from first_table only if most upper SELECT_LEX
449
1012
    do not contain tables.
450
1013
 
451
1014
    Because of above in place where should be at least one table in most
452
 
    outer Select_Lex we have following check:
 
1015
    outer SELECT_LEX we have following check:
453
1016
    assert(first_table == all_tables);
454
1017
    assert(first_table == all_tables && first_table != 0);
455
1018
  */
468
1031
    variables, but for now this is probably good enough.
469
1032
    Don't reset warnings when executing a stored routine.
470
1033
  */
471
 
  if (all_tables || ! lex->is_single_level_stmt())
472
 
  {
 
1034
  if (all_tables || !lex->is_single_level_stmt())
473
1035
    drizzle_reset_errors(session, 0);
474
 
  }
475
 
 
476
 
  assert(session->transaction.stmt.hasModifiedNonTransData() == false);
477
 
 
478
 
  /* now we are ready to execute the statement */
479
 
  res= lex->statement->execute();
 
1036
 
 
1037
  if (unlikely(session->slave_thread))
 
1038
  {
 
1039
    /*
 
1040
      Check if statment should be skipped because of slave filtering
 
1041
      rules
 
1042
 
 
1043
      Exceptions are:
 
1044
      - UPDATE MULTI: For this statement, we want to check the filtering
 
1045
        rules later in the code
 
1046
      - SET: we always execute it (Not that many SET commands exists in
 
1047
        the binary log anyway -- only 4.1 masters write SET statements,
 
1048
        in 5.0 there are no SET statements in the binary log)
 
1049
      - DROP TEMPORARY TABLE IF EXISTS: we always execute it (otherwise we
 
1050
        have stale files on slave caused by exclusion of one tmp table).
 
1051
    */
 
1052
    if (!(lex->sql_command == SQLCOM_UPDATE_MULTI) &&
 
1053
        !(lex->sql_command == SQLCOM_SET_OPTION) &&
 
1054
        !(lex->sql_command == SQLCOM_DROP_TABLE &&
 
1055
          lex->drop_temporary && lex->drop_if_exists) &&
 
1056
        all_tables_not_ok(session, all_tables))
 
1057
    {
 
1058
      /* we warn the slave SQL thread */
 
1059
      my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0));
 
1060
      return(0);
 
1061
    }
 
1062
  }
 
1063
 
 
1064
  status_var_increment(session->status_var.com_stat[lex->sql_command]);
 
1065
 
 
1066
  assert(session->transaction.stmt.modified_non_trans_table == false);
 
1067
 
 
1068
  switch (lex->sql_command) {
 
1069
  case SQLCOM_SHOW_STATUS:
 
1070
  {
 
1071
    system_status_var old_status_var= session->status_var;
 
1072
    session->initial_status_var= &old_status_var;
 
1073
    res= execute_sqlcom_select(session, all_tables);
 
1074
    /* Don't log SHOW STATUS commands to slow query log */
 
1075
    session->server_status&= ~(SERVER_QUERY_NO_INDEX_USED |
 
1076
                           SERVER_QUERY_NO_GOOD_INDEX_USED);
 
1077
    /*
 
1078
      restore status variables, as we don't want 'show status' to cause
 
1079
      changes
 
1080
    */
 
1081
    pthread_mutex_lock(&LOCK_status);
 
1082
    add_diff_to_status(&global_status_var, &session->status_var,
 
1083
                       &old_status_var);
 
1084
    session->status_var= old_status_var;
 
1085
    pthread_mutex_unlock(&LOCK_status);
 
1086
    break;
 
1087
  }
 
1088
  case SQLCOM_SHOW_DATABASES:
 
1089
  case SQLCOM_SHOW_TABLES:
 
1090
  case SQLCOM_SHOW_TABLE_STATUS:
 
1091
  case SQLCOM_SHOW_OPEN_TABLES:
 
1092
  case SQLCOM_SHOW_FIELDS:
 
1093
  case SQLCOM_SHOW_KEYS:
 
1094
  case SQLCOM_SHOW_VARIABLES:
 
1095
  case SQLCOM_SELECT:
 
1096
  {
 
1097
    session->status_var.last_query_cost= 0.0;
 
1098
    res= execute_sqlcom_select(session, all_tables);
 
1099
    break;
 
1100
  }
 
1101
  case SQLCOM_EMPTY_QUERY:
 
1102
    my_ok(session);
 
1103
    break;
 
1104
 
 
1105
  case SQLCOM_PURGE:
 
1106
  {
 
1107
    res = purge_master_logs(session, lex->to_log);
 
1108
    break;
 
1109
  }
 
1110
  case SQLCOM_PURGE_BEFORE:
 
1111
  {
 
1112
    Item *it;
 
1113
 
 
1114
    /* PURGE MASTER LOGS BEFORE 'data' */
 
1115
    it= (Item *)lex->value_list.head();
 
1116
    if ((!it->fixed && it->fix_fields(lex->session, &it)) ||
 
1117
        it->check_cols(1))
 
1118
    {
 
1119
      my_error(ER_WRONG_ARGUMENTS, MYF(0), "PURGE LOGS BEFORE");
 
1120
      goto error;
 
1121
    }
 
1122
    it= new Item_func_unix_timestamp(it);
 
1123
    /*
 
1124
      it is OK only emulate fix_fieds, because we need only
 
1125
      value of constant
 
1126
    */
 
1127
    it->quick_fix_field();
 
1128
    res = purge_master_logs_before_date(session, (ulong)it->val_int());
 
1129
    break;
 
1130
  }
 
1131
  case SQLCOM_SHOW_WARNS:
 
1132
  {
 
1133
    res= mysqld_show_warnings(session, (uint32_t)
 
1134
                              ((1L << (uint32_t) DRIZZLE_ERROR::WARN_LEVEL_NOTE) |
 
1135
                               (1L << (uint32_t) DRIZZLE_ERROR::WARN_LEVEL_WARN) |
 
1136
                               (1L << (uint32_t) DRIZZLE_ERROR::WARN_LEVEL_ERROR)
 
1137
                               ));
 
1138
    break;
 
1139
  }
 
1140
  case SQLCOM_SHOW_ERRORS:
 
1141
  {
 
1142
    res= mysqld_show_warnings(session, (uint32_t)
 
1143
                              (1L << (uint32_t) DRIZZLE_ERROR::WARN_LEVEL_ERROR));
 
1144
    break;
 
1145
  }
 
1146
  case SQLCOM_ASSIGN_TO_KEYCACHE:
 
1147
  {
 
1148
    assert(first_table == all_tables && first_table != 0);
 
1149
    res= mysql_assign_to_keycache(session, first_table, &lex->ident);
 
1150
    break;
 
1151
  }
 
1152
  case SQLCOM_CHANGE_MASTER:
 
1153
  {
 
1154
    pthread_mutex_lock(&LOCK_active_mi);
 
1155
    res = change_master(session,active_mi);
 
1156
    pthread_mutex_unlock(&LOCK_active_mi);
 
1157
    break;
 
1158
  }
 
1159
  case SQLCOM_SHOW_SLAVE_STAT:
 
1160
  {
 
1161
    pthread_mutex_lock(&LOCK_active_mi);
 
1162
    if (active_mi != NULL)
 
1163
    {
 
1164
      res = show_master_info(session, active_mi);
 
1165
    }
 
1166
    else
 
1167
    {
 
1168
      push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN, 0,
 
1169
                   "the master info structure does not exist");
 
1170
      my_ok(session);
 
1171
    }
 
1172
    pthread_mutex_unlock(&LOCK_active_mi);
 
1173
    break;
 
1174
  }
 
1175
  case SQLCOM_SHOW_MASTER_STAT:
 
1176
  {
 
1177
    res = show_binlog_info(session);
 
1178
    break;
 
1179
  }
 
1180
 
 
1181
  case SQLCOM_SHOW_ENGINE_STATUS:
 
1182
    {
 
1183
      res = ha_show_status(session, lex->create_info.db_type, HA_ENGINE_STATUS);
 
1184
      break;
 
1185
    }
 
1186
  case SQLCOM_CREATE_TABLE:
 
1187
  {
 
1188
    /* If CREATE TABLE of non-temporary table, do implicit commit */
 
1189
    if (!(lex->create_info.options & HA_LEX_CREATE_TMP_TABLE))
 
1190
    {
 
1191
      if (end_active_trans(session))
 
1192
      {
 
1193
        res= -1;
 
1194
        break;
 
1195
      }
 
1196
    }
 
1197
    assert(first_table == all_tables && first_table != 0);
 
1198
    bool link_to_local;
 
1199
    // Skip first table, which is the table we are creating
 
1200
    TableList *create_table= lex->unlink_first_table(&link_to_local);
 
1201
    TableList *select_tables= lex->query_tables;
 
1202
    /*
 
1203
      Code below (especially in mysql_create_table() and select_create
 
1204
      methods) may modify HA_CREATE_INFO structure in LEX, so we have to
 
1205
      use a copy of this structure to make execution prepared statement-
 
1206
      safe. A shallow copy is enough as this code won't modify any memory
 
1207
      referenced from this structure.
 
1208
    */
 
1209
    HA_CREATE_INFO create_info(lex->create_info);
 
1210
    /*
 
1211
      We need to copy alter_info for the same reasons of re-execution
 
1212
      safety, only in case of Alter_info we have to do (almost) a deep
 
1213
      copy.
 
1214
    */
 
1215
    Alter_info alter_info(lex->alter_info, session->mem_root);
 
1216
 
 
1217
    if (session->is_fatal_error)
 
1218
    {
 
1219
      /* If out of memory when creating a copy of alter_info. */
 
1220
      res= 1;
 
1221
      goto end_with_restore_list;
 
1222
    }
 
1223
 
 
1224
    if ((res= create_table_precheck(session, select_tables, create_table)))
 
1225
      goto end_with_restore_list;
 
1226
 
 
1227
    /* Might have been updated in create_table_precheck */
 
1228
    create_info.alias= create_table->alias;
 
1229
 
 
1230
#ifdef HAVE_READLINK
 
1231
    /* Fix names if symlinked tables */
 
1232
    if (append_file_to_dir(session, &create_info.data_file_name,
 
1233
                           create_table->table_name) ||
 
1234
        append_file_to_dir(session, &create_info.index_file_name,
 
1235
                           create_table->table_name))
 
1236
      goto end_with_restore_list;
 
1237
#endif
 
1238
    /*
 
1239
      If we are using SET CHARSET without DEFAULT, add an implicit
 
1240
      DEFAULT to not confuse old users. (This may change).
 
1241
    */
 
1242
    if ((create_info.used_fields &
 
1243
         (HA_CREATE_USED_DEFAULT_CHARSET | HA_CREATE_USED_CHARSET)) ==
 
1244
        HA_CREATE_USED_CHARSET)
 
1245
    {
 
1246
      create_info.used_fields&= ~HA_CREATE_USED_CHARSET;
 
1247
      create_info.used_fields|= HA_CREATE_USED_DEFAULT_CHARSET;
 
1248
      create_info.default_table_charset= create_info.table_charset;
 
1249
      create_info.table_charset= 0;
 
1250
    }
 
1251
    /*
 
1252
      The create-select command will open and read-lock the select table
 
1253
      and then create, open and write-lock the new table. If a global
 
1254
      read lock steps in, we get a deadlock. The write lock waits for
 
1255
      the global read lock, while the global read lock waits for the
 
1256
      select table to be closed. So we wait until the global readlock is
 
1257
      gone before starting both steps. Note that
 
1258
      wait_if_global_read_lock() sets a protection against a new global
 
1259
      read lock when it succeeds. This needs to be released by
 
1260
      start_waiting_global_read_lock(). We protect the normal CREATE
 
1261
      TABLE in the same way. That way we avoid that a new table is
 
1262
      created during a gobal read lock.
 
1263
    */
 
1264
    if (!session->locked_tables &&
 
1265
        !(need_start_waiting= !wait_if_global_read_lock(session, 0, 1)))
 
1266
    {
 
1267
      res= 1;
 
1268
      goto end_with_restore_list;
 
1269
    }
 
1270
    if (select_lex->item_list.elements)         // With select
 
1271
    {
 
1272
      select_result *result;
 
1273
 
 
1274
      select_lex->options|= SELECT_NO_UNLOCK;
 
1275
      unit->set_limit(select_lex);
 
1276
 
 
1277
      if (!(create_info.options & HA_LEX_CREATE_TMP_TABLE))
 
1278
      {
 
1279
        lex->link_first_table_back(create_table, link_to_local);
 
1280
        create_table->create= true;
 
1281
      }
 
1282
 
 
1283
      if (!(res= open_and_lock_tables(session, lex->query_tables)))
 
1284
      {
 
1285
        /*
 
1286
          Is table which we are changing used somewhere in other parts
 
1287
          of query
 
1288
        */
 
1289
        if (!(create_info.options & HA_LEX_CREATE_TMP_TABLE))
 
1290
        {
 
1291
          TableList *duplicate;
 
1292
          create_table= lex->unlink_first_table(&link_to_local);
 
1293
          if ((duplicate= unique_table(session, create_table, select_tables, 0)))
 
1294
          {
 
1295
            update_non_unique_table_error(create_table, "CREATE", duplicate);
 
1296
            res= 1;
 
1297
            goto end_with_restore_list;
 
1298
          }
 
1299
        }
 
1300
 
 
1301
        /*
 
1302
          select_create is currently not re-execution friendly and
 
1303
          needs to be created for every execution of a PS/SP.
 
1304
        */
 
1305
        if ((result= new select_create(create_table,
 
1306
                                       &create_info,
 
1307
                                       &alter_info,
 
1308
                                       select_lex->item_list,
 
1309
                                       lex->duplicates,
 
1310
                                       lex->ignore,
 
1311
                                       select_tables)))
 
1312
        {
 
1313
          /*
 
1314
            CREATE from SELECT give its SELECT_LEX for SELECT,
 
1315
            and item_list belong to SELECT
 
1316
          */
 
1317
          res= handle_select(session, lex, result, 0);
 
1318
          delete result;
 
1319
        }
 
1320
      }
 
1321
      else if (!(create_info.options & HA_LEX_CREATE_TMP_TABLE))
 
1322
        create_table= lex->unlink_first_table(&link_to_local);
 
1323
 
 
1324
    }
 
1325
    else
 
1326
    {
 
1327
      /* So that CREATE TEMPORARY TABLE gets to binlog at commit/rollback */
 
1328
      if (create_info.options & HA_LEX_CREATE_TMP_TABLE)
 
1329
        session->options|= OPTION_KEEP_LOG;
 
1330
      /* regular create */
 
1331
      if (create_info.options & HA_LEX_CREATE_TABLE_LIKE)
 
1332
        res= mysql_create_like_table(session, create_table, select_tables,
 
1333
                                     &create_info);
 
1334
      else
 
1335
      {
 
1336
        res= mysql_create_table(session, create_table->db,
 
1337
                                create_table->table_name, &create_info,
 
1338
                                &alter_info, 0, 0);
 
1339
      }
 
1340
      if (!res)
 
1341
        my_ok(session);
 
1342
    }
 
1343
 
 
1344
    /* put tables back for PS rexecuting */
 
1345
end_with_restore_list:
 
1346
    lex->link_first_table_back(create_table, link_to_local);
 
1347
    break;
 
1348
  }
 
1349
  case SQLCOM_CREATE_INDEX:
 
1350
    /* Fall through */
 
1351
  case SQLCOM_DROP_INDEX:
 
1352
  /*
 
1353
    CREATE INDEX and DROP INDEX are implemented by calling ALTER
 
1354
    TABLE with proper arguments.
 
1355
 
 
1356
    In the future ALTER TABLE will notice that the request is to
 
1357
    only add indexes and create these one by one for the existing
 
1358
    table without having to do a full rebuild.
 
1359
  */
 
1360
  {
 
1361
    /* Prepare stack copies to be re-execution safe */
 
1362
    HA_CREATE_INFO create_info;
 
1363
    Alter_info alter_info(lex->alter_info, session->mem_root);
 
1364
 
 
1365
    if (session->is_fatal_error) /* out of memory creating a copy of alter_info */
 
1366
      goto error;
 
1367
 
 
1368
    assert(first_table == all_tables && first_table != 0);
 
1369
    if (end_active_trans(session))
 
1370
      goto error;
 
1371
 
 
1372
    memset(&create_info, 0, sizeof(create_info));
 
1373
    create_info.db_type= 0;
 
1374
    create_info.row_type= ROW_TYPE_NOT_USED;
 
1375
    create_info.default_table_charset= session->variables.collation_database;
 
1376
 
 
1377
    res= mysql_alter_table(session, first_table->db, first_table->table_name,
 
1378
                           &create_info, first_table, &alter_info,
 
1379
                           0, (order_st*) 0, 0);
 
1380
    break;
 
1381
  }
 
1382
  case SQLCOM_SLAVE_START:
 
1383
  {
 
1384
    pthread_mutex_lock(&LOCK_active_mi);
 
1385
    start_slave(session,active_mi,1 /* net report*/);
 
1386
    pthread_mutex_unlock(&LOCK_active_mi);
 
1387
    break;
 
1388
  }
 
1389
  case SQLCOM_SLAVE_STOP:
 
1390
  /*
 
1391
    If the client thread has locked tables, a deadlock is possible.
 
1392
    Assume that
 
1393
    - the client thread does LOCK TABLE t READ.
 
1394
    - then the master updates t.
 
1395
    - then the SQL slave thread wants to update t,
 
1396
      so it waits for the client thread because t is locked by it.
 
1397
    - then the client thread does SLAVE STOP.
 
1398
      SLAVE STOP waits for the SQL slave thread to terminate its
 
1399
      update t, which waits for the client thread because t is locked by it.
 
1400
    To prevent that, refuse SLAVE STOP if the
 
1401
    client thread has locked tables
 
1402
  */
 
1403
  if (session->locked_tables || session->active_transaction() || session->global_read_lock)
 
1404
  {
 
1405
    my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
 
1406
               ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
 
1407
    goto error;
 
1408
  }
 
1409
  {
 
1410
    pthread_mutex_lock(&LOCK_active_mi);
 
1411
    stop_slave(session,active_mi,1/* net report*/);
 
1412
    pthread_mutex_unlock(&LOCK_active_mi);
 
1413
    break;
 
1414
  }
 
1415
 
 
1416
  case SQLCOM_ALTER_TABLE:
 
1417
    assert(first_table == all_tables && first_table != 0);
 
1418
    {
 
1419
      /*
 
1420
        Code in mysql_alter_table() may modify its HA_CREATE_INFO argument,
 
1421
        so we have to use a copy of this structure to make execution
 
1422
        prepared statement- safe. A shallow copy is enough as no memory
 
1423
        referenced from this structure will be modified.
 
1424
      */
 
1425
      HA_CREATE_INFO create_info(lex->create_info);
 
1426
      Alter_info alter_info(lex->alter_info, session->mem_root);
 
1427
 
 
1428
      if (session->is_fatal_error) /* out of memory creating a copy of alter_info */
 
1429
      {
 
1430
        goto error;
 
1431
      }
 
1432
 
 
1433
      /* Must be set in the parser */
 
1434
      assert(select_lex->db);
 
1435
 
 
1436
      { // Rename of table
 
1437
          TableList tmp_table;
 
1438
          memset(&tmp_table, 0, sizeof(tmp_table));
 
1439
          tmp_table.table_name= lex->name.str;
 
1440
          tmp_table.db=select_lex->db;
 
1441
      }
 
1442
 
 
1443
      /* Don't yet allow changing of symlinks with ALTER TABLE */
 
1444
      if (create_info.data_file_name)
 
1445
        push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN, 0,
 
1446
                     "DATA DIRECTORY option ignored");
 
1447
      if (create_info.index_file_name)
 
1448
        push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN, 0,
 
1449
                     "INDEX DIRECTORY option ignored");
 
1450
      create_info.data_file_name= create_info.index_file_name= NULL;
 
1451
      /* ALTER TABLE ends previous transaction */
 
1452
      if (end_active_trans(session))
 
1453
        goto error;
 
1454
 
 
1455
      if (!session->locked_tables &&
 
1456
          !(need_start_waiting= !wait_if_global_read_lock(session, 0, 1)))
 
1457
      {
 
1458
        res= 1;
 
1459
        break;
 
1460
      }
 
1461
 
 
1462
      res= mysql_alter_table(session, select_lex->db, lex->name.str,
 
1463
                             &create_info,
 
1464
                             first_table,
 
1465
                             &alter_info,
 
1466
                             select_lex->order_list.elements,
 
1467
                             (order_st *) select_lex->order_list.first,
 
1468
                             lex->ignore);
 
1469
      break;
 
1470
    }
 
1471
  case SQLCOM_RENAME_TABLE:
 
1472
  {
 
1473
    assert(first_table == all_tables && first_table != 0);
 
1474
    TableList *table;
 
1475
    for (table= first_table; table; table= table->next_local->next_local)
 
1476
    {
 
1477
      TableList old_list, new_list;
 
1478
      /*
 
1479
        we do not need initialize old_list and new_list because we will
 
1480
        come table[0] and table->next[0] there
 
1481
      */
 
1482
      old_list= table[0];
 
1483
      new_list= table->next_local[0];
 
1484
    }
 
1485
 
 
1486
    if (end_active_trans(session) || drizzle_rename_tables(session, first_table, 0))
 
1487
      {
 
1488
        goto error;
 
1489
      }
 
1490
    break;
 
1491
  }
 
1492
  case SQLCOM_SHOW_BINLOGS:
 
1493
    {
 
1494
      res = show_binlogs(session);
 
1495
      break;
 
1496
    }
 
1497
  case SQLCOM_SHOW_CREATE:
 
1498
    assert(first_table == all_tables && first_table != 0);
 
1499
    {
 
1500
      res= mysqld_show_create(session, first_table);
 
1501
      break;
 
1502
    }
 
1503
  case SQLCOM_CHECKSUM:
 
1504
  {
 
1505
    assert(first_table == all_tables && first_table != 0);
 
1506
    res = mysql_checksum_table(session, first_table, &lex->check_opt);
 
1507
    break;
 
1508
  }
 
1509
  case SQLCOM_REPAIR:
 
1510
  {
 
1511
    assert(first_table == all_tables && first_table != 0);
 
1512
    res= mysql_repair_table(session, first_table, &lex->check_opt);
 
1513
    /* ! we write after unlocking the table */
 
1514
    /*
 
1515
      Presumably, REPAIR and binlog writing doesn't require synchronization
 
1516
    */
 
1517
    write_bin_log(session, true, session->query, session->query_length);
 
1518
    select_lex->table_list.first= (unsigned char*) first_table;
 
1519
    lex->query_tables=all_tables;
 
1520
    break;
 
1521
  }
 
1522
  case SQLCOM_CHECK:
 
1523
  {
 
1524
    assert(first_table == all_tables && first_table != 0);
 
1525
    res = mysql_check_table(session, first_table, &lex->check_opt);
 
1526
    select_lex->table_list.first= (unsigned char*) first_table;
 
1527
    lex->query_tables=all_tables;
 
1528
    break;
 
1529
  }
 
1530
  case SQLCOM_ANALYZE:
 
1531
  {
 
1532
    assert(first_table == all_tables && first_table != 0);
 
1533
    res= mysql_analyze_table(session, first_table, &lex->check_opt);
 
1534
    /* ! we write after unlocking the table */
 
1535
    write_bin_log(session, true, session->query, session->query_length);
 
1536
    select_lex->table_list.first= (unsigned char*) first_table;
 
1537
    lex->query_tables=all_tables;
 
1538
    break;
 
1539
  }
 
1540
 
 
1541
  case SQLCOM_OPTIMIZE:
 
1542
  {
 
1543
    assert(first_table == all_tables && first_table != 0);
 
1544
    res= mysql_optimize_table(session, first_table, &lex->check_opt);
 
1545
    /* ! we write after unlocking the table */
 
1546
    write_bin_log(session, true, session->query, session->query_length);
 
1547
    select_lex->table_list.first= (unsigned char*) first_table;
 
1548
    lex->query_tables=all_tables;
 
1549
    break;
 
1550
  }
 
1551
  case SQLCOM_UPDATE:
 
1552
    assert(first_table == all_tables && first_table != 0);
 
1553
    if (update_precheck(session, all_tables))
 
1554
      break;
 
1555
    assert(select_lex->offset_limit == 0);
 
1556
    unit->set_limit(select_lex);
 
1557
    res= (up_result= mysql_update(session, all_tables,
 
1558
                                  select_lex->item_list,
 
1559
                                  lex->value_list,
 
1560
                                  select_lex->where,
 
1561
                                  select_lex->order_list.elements,
 
1562
                                  (order_st *) select_lex->order_list.first,
 
1563
                                  unit->select_limit_cnt,
 
1564
                                  lex->duplicates, lex->ignore));
 
1565
    /* mysql_update return 2 if we need to switch to multi-update */
 
1566
    if (up_result != 2)
 
1567
      break;
 
1568
    /* Fall through */
 
1569
  case SQLCOM_UPDATE_MULTI:
 
1570
  {
 
1571
    assert(first_table == all_tables && first_table != 0);
 
1572
    /* if we switched from normal update, rights are checked */
 
1573
    if (up_result != 2)
 
1574
    {
 
1575
      if ((res= multi_update_precheck(session, all_tables)))
 
1576
        break;
 
1577
    }
 
1578
    else
 
1579
      res= 0;
 
1580
 
 
1581
    res= mysql_multi_update_prepare(session);
 
1582
 
 
1583
    /* Check slave filtering rules */
 
1584
    if (unlikely(session->slave_thread))
 
1585
    {
 
1586
      if (all_tables_not_ok(session, all_tables))
 
1587
      {
 
1588
        if (res!= 0)
 
1589
        {
 
1590
          res= 0;             /* don't care of prev failure  */
 
1591
          session->clear_error(); /* filters are of highest prior */
 
1592
        }
 
1593
        /* we warn the slave SQL thread */
 
1594
        my_error(ER_SLAVE_IGNORED_TABLE, MYF(0));
 
1595
        break;
 
1596
      }
 
1597
      if (res)
 
1598
        break;
 
1599
    }
 
1600
    else
 
1601
    {
 
1602
      if (res)
 
1603
        break;
 
1604
 
 
1605
    }  /* unlikely */
 
1606
 
 
1607
    res= mysql_multi_update(session, all_tables,
 
1608
                            &select_lex->item_list,
 
1609
                            &lex->value_list,
 
1610
                            select_lex->where,
 
1611
                            select_lex->options,
 
1612
                            lex->duplicates, lex->ignore, unit, select_lex);
 
1613
    break;
 
1614
  }
 
1615
  case SQLCOM_REPLACE:
 
1616
  case SQLCOM_INSERT:
 
1617
  {
 
1618
    assert(first_table == all_tables && first_table != 0);
 
1619
    if ((res= insert_precheck(session, all_tables)))
 
1620
      break;
 
1621
 
 
1622
    if (!session->locked_tables &&
 
1623
        !(need_start_waiting= !wait_if_global_read_lock(session, 0, 1)))
 
1624
    {
 
1625
      res= 1;
 
1626
      break;
 
1627
    }
 
1628
 
 
1629
    res= mysql_insert(session, all_tables, lex->field_list, lex->many_values,
 
1630
                      lex->update_list, lex->value_list,
 
1631
                      lex->duplicates, lex->ignore);
 
1632
 
 
1633
    break;
 
1634
  }
 
1635
  case SQLCOM_REPLACE_SELECT:
 
1636
  case SQLCOM_INSERT_SELECT:
 
1637
  {
 
1638
    select_result *sel_result;
 
1639
    assert(first_table == all_tables && first_table != 0);
 
1640
    if ((res= insert_precheck(session, all_tables)))
 
1641
      break;
 
1642
 
 
1643
    /* Fix lock for first table */
 
1644
    if (first_table->lock_type == TL_WRITE_DELAYED)
 
1645
      first_table->lock_type= TL_WRITE;
 
1646
 
 
1647
    /* Don't unlock tables until command is written to binary log */
 
1648
    select_lex->options|= SELECT_NO_UNLOCK;
 
1649
 
 
1650
    unit->set_limit(select_lex);
 
1651
 
 
1652
    if (! session->locked_tables &&
 
1653
        ! (need_start_waiting= ! wait_if_global_read_lock(session, 0, 1)))
 
1654
    {
 
1655
      res= 1;
 
1656
      break;
 
1657
    }
 
1658
 
 
1659
    if (!(res= open_and_lock_tables(session, all_tables)))
 
1660
    {
 
1661
      /* Skip first table, which is the table we are inserting in */
 
1662
      TableList *second_table= first_table->next_local;
 
1663
      select_lex->table_list.first= (unsigned char*) second_table;
 
1664
      select_lex->context.table_list=
 
1665
        select_lex->context.first_name_resolution_table= second_table;
 
1666
      res= mysql_insert_select_prepare(session);
 
1667
      if (!res && (sel_result= new select_insert(first_table,
 
1668
                                                 first_table->table,
 
1669
                                                 &lex->field_list,
 
1670
                                                 &lex->update_list,
 
1671
                                                 &lex->value_list,
 
1672
                                                 lex->duplicates,
 
1673
                                                 lex->ignore)))
 
1674
      {
 
1675
        res= handle_select(session, lex, sel_result, OPTION_SETUP_TABLES_DONE);
 
1676
        /*
 
1677
          Invalidate the table in the query cache if something changed
 
1678
          after unlocking when changes become visible.
 
1679
          TODO: this is workaround. right way will be move invalidating in
 
1680
          the unlock procedure.
 
1681
        */
 
1682
        if (first_table->lock_type ==  TL_WRITE_CONCURRENT_INSERT &&
 
1683
            session->lock)
 
1684
        {
 
1685
          /* INSERT ... SELECT should invalidate only the very first table */
 
1686
          TableList *save_table= first_table->next_local;
 
1687
          first_table->next_local= 0;
 
1688
          first_table->next_local= save_table;
 
1689
        }
 
1690
        delete sel_result;
 
1691
      }
 
1692
      /* revert changes for SP */
 
1693
      select_lex->table_list.first= (unsigned char*) first_table;
 
1694
    }
 
1695
 
 
1696
    break;
 
1697
  }
 
1698
  case SQLCOM_TRUNCATE:
 
1699
    if (end_active_trans(session))
 
1700
    {
 
1701
      res= -1;
 
1702
      break;
 
1703
    }
 
1704
    assert(first_table == all_tables && first_table != 0);
 
1705
    /*
 
1706
      Don't allow this within a transaction because we want to use
 
1707
      re-generate table
 
1708
    */
 
1709
    if (session->locked_tables || session->active_transaction())
 
1710
    {
 
1711
      my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
 
1712
                 ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
 
1713
      goto error;
 
1714
    }
 
1715
 
 
1716
    res= mysql_truncate(session, first_table, 0);
 
1717
 
 
1718
    break;
 
1719
  case SQLCOM_DELETE:
 
1720
  {
 
1721
    assert(first_table == all_tables && first_table != 0);
 
1722
    assert(select_lex->offset_limit == 0);
 
1723
    unit->set_limit(select_lex);
 
1724
 
 
1725
    if (!session->locked_tables &&
 
1726
        !(need_start_waiting= !wait_if_global_read_lock(session, 0, 1)))
 
1727
    {
 
1728
      res= 1;
 
1729
      break;
 
1730
    }
 
1731
 
 
1732
    res = mysql_delete(session, all_tables, select_lex->where,
 
1733
                       &select_lex->order_list,
 
1734
                       unit->select_limit_cnt, select_lex->options,
 
1735
                       false);
 
1736
    break;
 
1737
  }
 
1738
  case SQLCOM_DELETE_MULTI:
 
1739
  {
 
1740
    assert(first_table == all_tables && first_table != 0);
 
1741
    TableList *aux_tables=
 
1742
      (TableList *)session->lex->auxiliary_table_list.first;
 
1743
    multi_delete *del_result;
 
1744
 
 
1745
    if (!session->locked_tables &&
 
1746
        !(need_start_waiting= !wait_if_global_read_lock(session, 0, 1)))
 
1747
    {
 
1748
      res= 1;
 
1749
      break;
 
1750
    }
 
1751
 
 
1752
    if ((res= multi_delete_precheck(session, all_tables)))
 
1753
      break;
 
1754
 
 
1755
    /* condition will be true on SP re-excuting */
 
1756
    if (select_lex->item_list.elements != 0)
 
1757
      select_lex->item_list.empty();
 
1758
    if (add_item_to_list(session, new Item_null()))
 
1759
      goto error;
 
1760
 
 
1761
    session->set_proc_info("init");
 
1762
    if ((res= open_and_lock_tables(session, all_tables)))
 
1763
      break;
 
1764
 
 
1765
    if ((res= mysql_multi_delete_prepare(session)))
 
1766
      goto error;
 
1767
 
 
1768
    if (!session->is_fatal_error &&
 
1769
        (del_result= new multi_delete(aux_tables, lex->table_count)))
 
1770
    {
 
1771
      res= mysql_select(session, &select_lex->ref_pointer_array,
 
1772
                        select_lex->get_table_list(),
 
1773
                        select_lex->with_wild,
 
1774
                        select_lex->item_list,
 
1775
                        select_lex->where,
 
1776
                        0, (order_st *)NULL, (order_st *)NULL, (Item *)NULL,
 
1777
                        (order_st *)NULL,
 
1778
                        select_lex->options | session->options |
 
1779
                        SELECT_NO_JOIN_CACHE | SELECT_NO_UNLOCK |
 
1780
                        OPTION_SETUP_TABLES_DONE,
 
1781
                        del_result, unit, select_lex);
 
1782
      res|= session->is_error();
 
1783
      if (res)
 
1784
        del_result->abort();
 
1785
      delete del_result;
 
1786
    }
 
1787
    else
 
1788
      res= true;                                // Error
 
1789
    break;
 
1790
  }
 
1791
  case SQLCOM_DROP_TABLE:
 
1792
  {
 
1793
    assert(first_table == all_tables && first_table != 0);
 
1794
    if (!lex->drop_temporary)
 
1795
    {
 
1796
      if (end_active_trans(session))
 
1797
        goto error;
 
1798
    }
 
1799
    else
 
1800
    {
 
1801
      /*
 
1802
        If this is a slave thread, we may sometimes execute some
 
1803
        DROP / * 40005 TEMPORARY * / TABLE
 
1804
        that come from parts of binlogs (likely if we use RESET SLAVE or CHANGE
 
1805
        MASTER TO), while the temporary table has already been dropped.
 
1806
        To not generate such irrelevant "table does not exist errors",
 
1807
        we silently add IF EXISTS if TEMPORARY was used.
 
1808
      */
 
1809
      if (session->slave_thread)
 
1810
        lex->drop_if_exists= 1;
 
1811
 
 
1812
      /* So that DROP TEMPORARY TABLE gets to binlog at commit/rollback */
 
1813
      session->options|= OPTION_KEEP_LOG;
 
1814
    }
 
1815
    /* DDL and binlog write order protected by LOCK_open */
 
1816
    res= mysql_rm_table(session, first_table, lex->drop_if_exists, lex->drop_temporary);
 
1817
  }
 
1818
  break;
 
1819
  case SQLCOM_SHOW_PROCESSLIST:
 
1820
    mysqld_list_processes(session, NULL, lex->verbose);
 
1821
    break;
 
1822
  case SQLCOM_SHOW_ENGINE_LOGS:
 
1823
    {
 
1824
      res= ha_show_status(session, lex->create_info.db_type, HA_ENGINE_LOGS);
 
1825
      break;
 
1826
    }
 
1827
  case SQLCOM_CHANGE_DB:
 
1828
  {
 
1829
    LEX_STRING db_str= { (char *) select_lex->db, strlen(select_lex->db) };
 
1830
 
 
1831
    if (!mysql_change_db(session, &db_str, false))
 
1832
      my_ok(session);
 
1833
 
 
1834
    break;
 
1835
  }
 
1836
 
 
1837
  case SQLCOM_LOAD:
 
1838
  {
 
1839
    assert(first_table == all_tables && first_table != 0);
 
1840
    if (lex->local_file)
 
1841
    {
 
1842
      if (!(session->client_capabilities & CLIENT_LOCAL_FILES) ||
 
1843
          !opt_local_infile)
 
1844
      {
 
1845
        my_message(ER_NOT_ALLOWED_COMMAND, ER(ER_NOT_ALLOWED_COMMAND), MYF(0));
 
1846
        goto error;
 
1847
      }
 
1848
    }
 
1849
 
 
1850
    res= mysql_load(session, lex->exchange, first_table, lex->field_list,
 
1851
                    lex->update_list, lex->value_list, lex->duplicates,
 
1852
                    lex->ignore, (bool) lex->local_file);
 
1853
    break;
 
1854
  }
 
1855
 
 
1856
  case SQLCOM_SET_OPTION:
 
1857
  {
 
1858
    List<set_var_base> *lex_var_list= &lex->var_list;
 
1859
 
 
1860
    if (lex->autocommit && end_active_trans(session))
 
1861
      goto error;
 
1862
 
 
1863
    if (open_and_lock_tables(session, all_tables))
 
1864
      goto error;
 
1865
    if (!(res= sql_set_variables(session, lex_var_list)))
 
1866
    {
 
1867
      my_ok(session);
 
1868
    }
 
1869
    else
 
1870
    {
 
1871
      /*
 
1872
        We encountered some sort of error, but no message was sent.
 
1873
        Send something semi-generic here since we don't know which
 
1874
        assignment in the list caused the error.
 
1875
      */
 
1876
      if (!session->is_error())
 
1877
        my_error(ER_WRONG_ARGUMENTS,MYF(0),"SET");
 
1878
      goto error;
 
1879
    }
 
1880
 
 
1881
    break;
 
1882
  }
 
1883
 
 
1884
  case SQLCOM_UNLOCK_TABLES:
 
1885
    /*
 
1886
      It is critical for mysqldump --single-transaction --master-data that
 
1887
      UNLOCK TABLES does not implicitely commit a connection which has only
 
1888
      done FLUSH TABLES WITH READ LOCK + BEGIN. If this assumption becomes
 
1889
      false, mysqldump will not work.
 
1890
    */
 
1891
    unlock_locked_tables(session);
 
1892
    if (session->options & OPTION_TABLE_LOCK)
 
1893
    {
 
1894
      end_active_trans(session);
 
1895
      session->options&= ~(OPTION_TABLE_LOCK);
 
1896
    }
 
1897
    if (session->global_read_lock)
 
1898
      unlock_global_read_lock(session);
 
1899
    my_ok(session);
 
1900
    break;
 
1901
  case SQLCOM_LOCK_TABLES:
 
1902
    /*
 
1903
      We try to take transactional locks if
 
1904
      - only transactional locks are requested (lex->lock_transactional) and
 
1905
      - no non-transactional locks exist (!session->locked_tables).
 
1906
    */
 
1907
    if (lex->lock_transactional && !session->locked_tables)
 
1908
    {
 
1909
      int rc;
 
1910
      /*
 
1911
        All requested locks are transactional and no non-transactional
 
1912
        locks exist.
 
1913
      */
 
1914
      if ((rc= try_transactional_lock(session, all_tables)) == -1)
 
1915
        goto error;
 
1916
      if (rc == 0)
 
1917
      {
 
1918
        my_ok(session);
 
1919
        break;
 
1920
      }
 
1921
      /*
 
1922
        Non-transactional locking has been requested or
 
1923
        non-transactional locks exist already or transactional locks are
 
1924
        not supported by all storage engines. Take non-transactional
 
1925
        locks.
 
1926
      */
 
1927
    }
 
1928
    /*
 
1929
      One or more requested locks are non-transactional and/or
 
1930
      non-transactional locks exist or a storage engine does not support
 
1931
      transactional locks. Check if at least one transactional lock is
 
1932
      requested. If yes, warn about the conversion to non-transactional
 
1933
      locks or abort in strict mode.
 
1934
    */
 
1935
    if (check_transactional_lock(session, all_tables))
 
1936
      goto error;
 
1937
    unlock_locked_tables(session);
 
1938
    /* we must end the trasaction first, regardless of anything */
 
1939
    if (end_active_trans(session))
 
1940
      goto error;
 
1941
    session->in_lock_tables=1;
 
1942
    session->options|= OPTION_TABLE_LOCK;
 
1943
 
 
1944
    if (!(res= simple_open_n_lock_tables(session, all_tables)))
 
1945
    {
 
1946
      session->locked_tables=session->lock;
 
1947
      session->lock=0;
 
1948
      (void) set_handler_table_locks(session, all_tables, false);
 
1949
      my_ok(session);
 
1950
    }
 
1951
    else
 
1952
    {
 
1953
      /*
 
1954
        Need to end the current transaction, so the storage engine (InnoDB)
 
1955
        can free its locks if LOCK TABLES locked some tables before finding
 
1956
        that it can't lock a table in its list
 
1957
      */
 
1958
      ha_autocommit_or_rollback(session, 1);
 
1959
      end_active_trans(session);
 
1960
      session->options&= ~(OPTION_TABLE_LOCK);
 
1961
    }
 
1962
    session->in_lock_tables=0;
 
1963
    break;
 
1964
  case SQLCOM_CREATE_DB:
 
1965
  {
 
1966
    /*
 
1967
      As mysql_create_db() may modify HA_CREATE_INFO structure passed to
 
1968
      it, we need to use a copy of LEX::create_info to make execution
 
1969
      prepared statement- safe.
 
1970
    */
 
1971
    HA_CREATE_INFO create_info(lex->create_info);
 
1972
    if (end_active_trans(session))
 
1973
    {
 
1974
      res= -1;
 
1975
      break;
 
1976
    }
 
1977
    char *alias;
 
1978
    if (!(alias=session->strmake(lex->name.str, lex->name.length)) ||
 
1979
        check_db_name(&lex->name))
 
1980
    {
 
1981
      my_error(ER_WRONG_DB_NAME, MYF(0), lex->name.str);
 
1982
      break;
 
1983
    }
 
1984
    res= mysql_create_db(session,(lower_case_table_names == 2 ? alias :
 
1985
                              lex->name.str), &create_info, 0);
 
1986
    break;
 
1987
  }
 
1988
  case SQLCOM_DROP_DB:
 
1989
  {
 
1990
    if (end_active_trans(session))
 
1991
    {
 
1992
      res= -1;
 
1993
      break;
 
1994
    }
 
1995
    if (check_db_name(&lex->name))
 
1996
    {
 
1997
      my_error(ER_WRONG_DB_NAME, MYF(0), lex->name.str);
 
1998
      break;
 
1999
    }
 
2000
    if (session->locked_tables || session->active_transaction())
 
2001
    {
 
2002
      my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
 
2003
                 ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
 
2004
      goto error;
 
2005
    }
 
2006
    res= mysql_rm_db(session, lex->name.str, lex->drop_if_exists, 0);
 
2007
    break;
 
2008
  }
 
2009
  case SQLCOM_ALTER_DB:
 
2010
  {
 
2011
    LEX_STRING *db= &lex->name;
 
2012
    HA_CREATE_INFO create_info(lex->create_info);
 
2013
    if (check_db_name(db))
 
2014
    {
 
2015
      my_error(ER_WRONG_DB_NAME, MYF(0), db->str);
 
2016
      break;
 
2017
    }
 
2018
    if (session->locked_tables || session->active_transaction())
 
2019
    {
 
2020
      my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
 
2021
                 ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
 
2022
      goto error;
 
2023
    }
 
2024
    res= mysql_alter_db(session, db->str, &create_info);
 
2025
    break;
 
2026
  }
 
2027
  case SQLCOM_SHOW_CREATE_DB:
 
2028
  {
 
2029
    if (check_db_name(&lex->name))
 
2030
    {
 
2031
      my_error(ER_WRONG_DB_NAME, MYF(0), lex->name.str);
 
2032
      break;
 
2033
    }
 
2034
    res= mysqld_show_create_db(session, lex->name.str, &lex->create_info);
 
2035
    break;
 
2036
  }
 
2037
  case SQLCOM_RESET:
 
2038
  case SQLCOM_FLUSH:
 
2039
  {
 
2040
    bool write_to_binlog;
 
2041
 
 
2042
    /*
 
2043
      reload_cache() will tell us if we are allowed to write to the
 
2044
      binlog or not.
 
2045
    */
 
2046
    if (!reload_cache(session, lex->type, first_table, &write_to_binlog))
 
2047
    {
 
2048
      /*
 
2049
        We WANT to write and we CAN write.
 
2050
        ! we write after unlocking the table.
 
2051
      */
 
2052
      /*
 
2053
        Presumably, RESET and binlog writing doesn't require synchronization
 
2054
      */
 
2055
      write_bin_log(session, false, session->query, session->query_length);
 
2056
      my_ok(session);
 
2057
    }
 
2058
 
 
2059
    break;
 
2060
  }
 
2061
  case SQLCOM_KILL:
 
2062
  {
 
2063
    Item *it= (Item *)lex->value_list.head();
 
2064
 
 
2065
    if ((!it->fixed && it->fix_fields(lex->session, &it)) || it->check_cols(1))
 
2066
    {
 
2067
      my_message(ER_SET_CONSTANTS_ONLY, ER(ER_SET_CONSTANTS_ONLY),
 
2068
                 MYF(0));
 
2069
      goto error;
 
2070
    }
 
2071
    sql_kill(session, (ulong)it->val_int(), lex->type & ONLY_KILL_QUERY);
 
2072
    break;
 
2073
  }
 
2074
  case SQLCOM_BEGIN:
 
2075
    if (session->transaction.xid_state.xa_state != XA_NOTR)
 
2076
    {
 
2077
      my_error(ER_XAER_RMFAIL, MYF(0),
 
2078
               xa_state_names[session->transaction.xid_state.xa_state]);
 
2079
      break;
 
2080
    }
 
2081
    /*
 
2082
      Breakpoints for backup testing.
 
2083
    */
 
2084
    if (begin_trans(session))
 
2085
      goto error;
 
2086
    my_ok(session);
 
2087
    break;
 
2088
  case SQLCOM_COMMIT:
 
2089
    if (end_trans(session, lex->tx_release ? COMMIT_RELEASE :
 
2090
                              lex->tx_chain ? COMMIT_AND_CHAIN : COMMIT))
 
2091
      goto error;
 
2092
    my_ok(session);
 
2093
    break;
 
2094
  case SQLCOM_ROLLBACK:
 
2095
    if (end_trans(session, lex->tx_release ? ROLLBACK_RELEASE :
 
2096
                              lex->tx_chain ? ROLLBACK_AND_CHAIN : ROLLBACK))
 
2097
      goto error;
 
2098
    my_ok(session);
 
2099
    break;
 
2100
  case SQLCOM_RELEASE_SAVEPOINT:
 
2101
  {
 
2102
    SAVEPOINT *sv;
 
2103
    for (sv=session->transaction.savepoints; sv; sv=sv->prev)
 
2104
    {
 
2105
      if (my_strnncoll(system_charset_info,
 
2106
                       (unsigned char *)lex->ident.str, lex->ident.length,
 
2107
                       (unsigned char *)sv->name, sv->length) == 0)
 
2108
        break;
 
2109
    }
 
2110
    if (sv)
 
2111
    {
 
2112
      if (ha_release_savepoint(session, sv))
 
2113
        res= true; // cannot happen
 
2114
      else
 
2115
        my_ok(session);
 
2116
      session->transaction.savepoints=sv->prev;
 
2117
    }
 
2118
    else
 
2119
      my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "SAVEPOINT", lex->ident.str);
 
2120
    break;
 
2121
  }
 
2122
  case SQLCOM_ROLLBACK_TO_SAVEPOINT:
 
2123
  {
 
2124
    SAVEPOINT *sv;
 
2125
    for (sv=session->transaction.savepoints; sv; sv=sv->prev)
 
2126
    {
 
2127
      if (my_strnncoll(system_charset_info,
 
2128
                       (unsigned char *)lex->ident.str, lex->ident.length,
 
2129
                       (unsigned char *)sv->name, sv->length) == 0)
 
2130
        break;
 
2131
    }
 
2132
    if (sv)
 
2133
    {
 
2134
      if (ha_rollback_to_savepoint(session, sv))
 
2135
        res= true; // cannot happen
 
2136
      else
 
2137
      {
 
2138
        if (((session->options & OPTION_KEEP_LOG) ||
 
2139
             session->transaction.all.modified_non_trans_table) &&
 
2140
            !session->slave_thread)
 
2141
          push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
2142
                       ER_WARNING_NOT_COMPLETE_ROLLBACK,
 
2143
                       ER(ER_WARNING_NOT_COMPLETE_ROLLBACK));
 
2144
        my_ok(session);
 
2145
      }
 
2146
      session->transaction.savepoints=sv;
 
2147
    }
 
2148
    else
 
2149
      my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "SAVEPOINT", lex->ident.str);
 
2150
    break;
 
2151
  }
 
2152
  case SQLCOM_SAVEPOINT:
 
2153
    if (!(session->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) || !opt_using_transactions)
 
2154
      my_ok(session);
 
2155
    else
 
2156
    {
 
2157
      SAVEPOINT **sv, *newsv;
 
2158
      for (sv=&session->transaction.savepoints; *sv; sv=&(*sv)->prev)
 
2159
      {
 
2160
        if (my_strnncoll(system_charset_info,
 
2161
                         (unsigned char *)lex->ident.str, lex->ident.length,
 
2162
                         (unsigned char *)(*sv)->name, (*sv)->length) == 0)
 
2163
          break;
 
2164
      }
 
2165
      if (*sv) /* old savepoint of the same name exists */
 
2166
      {
 
2167
        newsv=*sv;
 
2168
        ha_release_savepoint(session, *sv); // it cannot fail
 
2169
        *sv=(*sv)->prev;
 
2170
      }
 
2171
      else if ((newsv=(SAVEPOINT *) alloc_root(&session->transaction.mem_root,
 
2172
                                               savepoint_alloc_size)) == 0)
 
2173
      {
 
2174
        my_error(ER_OUT_OF_RESOURCES, MYF(0));
 
2175
        break;
 
2176
      }
 
2177
      newsv->name=strmake_root(&session->transaction.mem_root,
 
2178
                               lex->ident.str, lex->ident.length);
 
2179
      newsv->length=lex->ident.length;
 
2180
      /*
 
2181
        if we'll get an error here, don't add new savepoint to the list.
 
2182
        we'll lose a little bit of memory in transaction mem_root, but it'll
 
2183
        be free'd when transaction ends anyway
 
2184
      */
 
2185
      if (ha_savepoint(session, newsv))
 
2186
        res= true;
 
2187
      else
 
2188
      {
 
2189
        newsv->prev=session->transaction.savepoints;
 
2190
        session->transaction.savepoints=newsv;
 
2191
        my_ok(session);
 
2192
      }
 
2193
    }
 
2194
    break;
 
2195
  case SQLCOM_BINLOG_BASE64_EVENT:
 
2196
  {
 
2197
    mysql_client_binlog_statement(session);
 
2198
    break;
 
2199
  }
 
2200
  default:
 
2201
    assert(0);                             /* Impossible */
 
2202
    my_ok(session);
 
2203
    break;
 
2204
  }
480
2205
  session->set_proc_info("query end");
 
2206
 
481
2207
  /*
482
2208
    The return value for ROW_COUNT() is "implementation dependent" if the
483
2209
    statement is not DELETE, INSERT or UPDATE, but -1 is what JDBC and ODBC
484
2210
    wants. We also keep the last value in case of SQLCOM_CALL or
485
2211
    SQLCOM_EXECUTE.
486
2212
  */
487
 
  if (! (sql_command_flags[lex->sql_command].test(CF_BIT_HAS_ROW_COUNT)))
488
 
  {
 
2213
  if (!(sql_command_flags[lex->sql_command].test(CF_BIT_HAS_ROW_COUNT)))
489
2214
    session->row_count_func= -1;
 
2215
 
 
2216
  goto finish;
 
2217
 
 
2218
error:
 
2219
  res= true;
 
2220
 
 
2221
finish:
 
2222
  if (need_start_waiting)
 
2223
  {
 
2224
    /*
 
2225
      Release the protection against the global read lock and wake
 
2226
      everyone, who might want to set a global read lock.
 
2227
    */
 
2228
    start_waiting_global_read_lock(session);
490
2229
  }
491
 
 
492
 
  return (res || session->is_error());
 
2230
  return(res || session->is_error());
493
2231
}
 
2232
 
494
2233
bool execute_sqlcom_select(Session *session, TableList *all_tables)
495
2234
{
496
2235
  LEX   *lex= session->lex;
497
2236
  select_result *result=lex->result;
498
 
  bool res= false;
 
2237
  bool res;
499
2238
  /* assign global limit variable if limit is not given */
500
2239
  {
501
 
    Select_Lex *param= lex->unit.global_parameters;
 
2240
    SELECT_LEX *param= lex->unit.global_parameters;
502
2241
    if (!param->explicit_limit)
503
2242
      param->select_limit=
504
2243
        new Item_int((uint64_t) session->variables.select_limit);
505
2244
  }
506
 
  if (not (res= session->openTablesLock(all_tables)))
 
2245
  if (!(res= open_and_lock_tables(session, all_tables)))
507
2246
  {
508
2247
    if (lex->describe)
509
2248
    {
514
2253
        even if the query itself redirects the output.
515
2254
      */
516
2255
      if (!(result= new select_send()))
517
 
        return true;
 
2256
        return 1;                               /* purecov: inspected */
518
2257
      session->send_explain_fields(result);
519
 
      optimizer::ExplainPlan planner;
520
 
      res= planner.explainUnion(session, &session->lex->unit, result);
 
2258
      res= mysql_explain_union(session, &session->lex->unit, result);
521
2259
      if (lex->describe & DESCRIBE_EXTENDED)
522
2260
      {
523
2261
        char buff[1024];
537
2275
    else
538
2276
    {
539
2277
      if (!result && !(result= new select_send()))
540
 
        return true;
541
 
 
542
 
      /* Init the Query Cache plugin */
543
 
      plugin::QueryCache::prepareResultset(session); 
 
2278
        return 1;                               /* purecov: inspected */
544
2279
      res= handle_select(session, lex, result, 0);
545
 
      /* Send the Resultset to the cache */
546
 
      plugin::QueryCache::setResultset(session); 
547
 
 
548
2280
      if (result != lex->result)
549
2281
        delete result;
550
2282
    }
589
2321
void
590
2322
mysql_init_select(LEX *lex)
591
2323
{
592
 
  Select_Lex *select_lex= lex->current_select;
 
2324
  SELECT_LEX *select_lex= lex->current_select;
593
2325
  select_lex->init_select();
594
2326
  lex->wild= 0;
595
2327
  if (select_lex == &lex->select_lex)
603
2335
bool
604
2336
mysql_new_select(LEX *lex, bool move_down)
605
2337
{
606
 
  Select_Lex *select_lex;
 
2338
  SELECT_LEX *select_lex;
607
2339
  Session *session= lex->session;
608
2340
 
609
 
  if (!(select_lex= new (session->mem_root) Select_Lex()))
 
2341
  if (!(select_lex= new (session->mem_root) SELECT_LEX()))
610
2342
    return(1);
611
2343
  select_lex->select_number= ++session->select_number;
612
2344
  select_lex->parent_lex= lex; /* Used in init_query. */
621
2353
  select_lex->nest_level= lex->nest_level;
622
2354
  if (move_down)
623
2355
  {
624
 
    Select_Lex_Unit *unit;
 
2356
    SELECT_LEX_UNIT *unit;
 
2357
    lex->subqueries= true;
625
2358
    /* first select_lex of subselect or derived table */
626
 
    if (!(unit= new (session->mem_root) Select_Lex_Unit()))
 
2359
    if (!(unit= new (session->mem_root) SELECT_LEX_UNIT()))
627
2360
      return(1);
628
2361
 
629
2362
    unit->init_query();
648
2381
      return(1);
649
2382
    }
650
2383
    select_lex->include_neighbour(lex->current_select);
651
 
    Select_Lex_Unit *unit= select_lex->master_unit();
 
2384
    SELECT_LEX_UNIT *unit= select_lex->master_unit();
652
2385
    if (!unit->fake_select_lex && unit->add_fake_select_lex(lex->session))
653
2386
      return(1);
654
2387
    select_lex->context.outer_context=
656
2389
  }
657
2390
 
658
2391
  select_lex->master_unit()->global_parameters= select_lex;
659
 
  select_lex->include_global((Select_Lex_Node**)&lex->all_selects_list);
 
2392
  select_lex->include_global((st_select_lex_node**)&lex->all_selects_list);
660
2393
  lex->current_select= select_lex;
661
2394
  /*
662
2395
    in subquery is SELECT query and we allow resolution of names in SELECT
698
2431
  */
699
2432
  if ((var= get_system_var(session, OPT_SESSION, tmp, null_lex_string)))
700
2433
  {
701
 
    end+= snprintf(buff, sizeof(buff), "@@session.%s", var_name);
 
2434
    end+= sprintf(buff, "@@session.%s", var_name);
702
2435
    var->set_name(buff, end-buff, system_charset_info);
703
 
    session->add_item_to_list(var);
 
2436
    add_item_to_list(session, var);
704
2437
  }
705
2438
  return;
706
2439
}
707
2440
 
708
2441
 
 
2442
void mysql_init_multi_delete(LEX *lex)
 
2443
{
 
2444
  lex->sql_command=  SQLCOM_DELETE_MULTI;
 
2445
  mysql_init_select(lex);
 
2446
  lex->select_lex.select_limit= 0;
 
2447
  lex->unit.select_limit_cnt= HA_POS_ERROR;
 
2448
  lex->select_lex.table_list.save_and_clear(&lex->auxiliary_table_list);
 
2449
  lex->lock_option= TL_READ;
 
2450
  lex->query_tables= 0;
 
2451
  lex->query_tables_last= &lex->query_tables;
 
2452
}
 
2453
 
 
2454
 
 
2455
/*
 
2456
  When you modify mysql_parse(), you may need to mofify
 
2457
  mysql_test_parse_for_slave() in this same file.
 
2458
*/
 
2459
 
709
2460
/**
710
2461
  Parse a query.
711
2462
 
712
2463
  @param       session     Current thread
713
2464
  @param       inBuf   Begining of the query text
714
2465
  @param       length  Length of the query text
 
2466
  @param[out]  found_semicolon For multi queries, position of the character of
 
2467
                               the next query in the query text.
715
2468
*/
716
2469
 
717
 
void mysql_parse(Session *session, const char *inBuf, uint32_t length)
 
2470
void mysql_parse(Session *session, const char *inBuf, uint32_t length,
 
2471
                 const char ** found_semicolon)
718
2472
{
719
 
  boost::posix_time::ptime start_time=boost::posix_time::microsec_clock::local_time();
720
 
  session->lex->start(session);
721
 
 
 
2473
  /*
 
2474
    Warning.
 
2475
    The purpose of query_cache_send_result_to_client() is to lookup the
 
2476
    query in the query cache first, to avoid parsing and executing it.
 
2477
    So, the natural implementation would be to:
 
2478
    - first, call query_cache_send_result_to_client,
 
2479
    - second, if caching failed, initialise the lexical and syntactic parser.
 
2480
    The problem is that the query cache depends on a clean initialization
 
2481
    of (among others) lex->safe_to_cache_query and session->server_status,
 
2482
    which are reset respectively in
 
2483
    - lex_start()
 
2484
    - mysql_reset_session_for_next_command()
 
2485
    So, initializing the lexical analyser *before* using the query cache
 
2486
    is required for the cache to work properly.
 
2487
    FIXME: cleanup the dependencies in the code to simplify this.
 
2488
  */
 
2489
  lex_start(session);
722
2490
  session->reset_for_next_command();
723
 
  /* Check if the Query is Cached if and return true if yes
724
 
   * TODO the plugin has to make sure that the query is cacheble
725
 
   * by setting the query_safe_cache param to TRUE
726
 
   */
727
 
  bool res= true;
728
 
  if (plugin::QueryCache::isCached(session))
729
 
  {
730
 
    res= plugin::QueryCache::sendCachedResultset(session);
731
 
  }
732
 
  if (not res)
733
 
  {
734
 
    return;
735
 
  }
 
2491
 
 
2492
  {
 
2493
    LEX *lex= session->lex;
 
2494
 
 
2495
    Lex_input_stream lip(session, inBuf, length);
 
2496
 
 
2497
    bool err= parse_sql(session, &lip);
 
2498
    *found_semicolon= lip.found_semicolon;
 
2499
 
 
2500
    if (!err)
 
2501
    {
 
2502
      {
 
2503
        if (! session->is_error())
 
2504
        {
 
2505
          /*
 
2506
            Binlog logs a string starting from session->query and having length
 
2507
            session->query_length; so we set session->query_length correctly (to not
 
2508
            log several statements in one event, when we executed only first).
 
2509
            We set it to not see the ';' (otherwise it would get into binlog
 
2510
            and Query_log_event::print() would give ';;' output).
 
2511
            This also helps display only the current query in SHOW
 
2512
            PROCESSLIST.
 
2513
            Note that we don't need LOCK_thread_count to modify query_length.
 
2514
          */
 
2515
          if (*found_semicolon &&
 
2516
              (session->query_length= (ulong)(*found_semicolon - session->query)))
 
2517
            session->query_length--;
 
2518
          /* Actually execute the query */
 
2519
          mysql_execute_command(session);
 
2520
        }
 
2521
      }
 
2522
    }
 
2523
    else
 
2524
    {
 
2525
      assert(session->is_error());
 
2526
    }
 
2527
    lex->unit.cleanup();
 
2528
    session->set_proc_info("freeing items");
 
2529
    session->end_statement();
 
2530
    session->cleanup_after_query();
 
2531
    assert(session->change_list.is_empty());
 
2532
  }
 
2533
 
 
2534
  return;
 
2535
}
 
2536
 
 
2537
 
 
2538
/*
 
2539
  Usable by the replication SQL thread only: just parse a query to know if it
 
2540
  can be ignored because of replicate-*-table rules.
 
2541
 
 
2542
  @retval
 
2543
    0   cannot be ignored
 
2544
  @retval
 
2545
    1   can be ignored
 
2546
*/
 
2547
 
 
2548
bool mysql_test_parse_for_slave(Session *session, char *inBuf, uint32_t length)
 
2549
{
736
2550
  LEX *lex= session->lex;
 
2551
  bool error= 0;
 
2552
 
737
2553
  Lex_input_stream lip(session, inBuf, length);
738
 
  bool err= parse_sql(session, &lip);
739
 
  if (!err)
740
 
  {
741
 
    {
742
 
      if (not session->is_error())
743
 
      {
744
 
        DRIZZLE_QUERY_EXEC_START(session->getQueryString()->c_str(),
745
 
                                 session->thread_id,
746
 
                                 const_cast<const char *>(session->schema()->c_str()));
747
 
        // Implement Views here --Brian
748
 
        /* Actually execute the query */
749
 
        try 
750
 
        {
751
 
          mysql_execute_command(session);
752
 
        }
753
 
        catch (...)
754
 
        {
755
 
          // Just try to catch any random failures that could have come
756
 
          // during execution.
757
 
          unireg_abort(1);
758
 
        }
759
 
        DRIZZLE_QUERY_EXEC_DONE(0);
760
 
      }
761
 
    }
762
 
  }
763
 
  else
764
 
  {
765
 
    assert(session->is_error());
766
 
  }
767
 
  lex->unit.cleanup();
768
 
  session->set_proc_info("freeing items");
 
2554
  lex_start(session);
 
2555
  session->reset_for_next_command();
 
2556
 
 
2557
  if (!parse_sql(session, &lip) &&
 
2558
      all_tables_not_ok(session,(TableList*) lex->select_lex.table_list.first))
 
2559
    error= 1;                  /* Ignore question */
769
2560
  session->end_statement();
770
2561
  session->cleanup_after_query();
771
 
  boost::posix_time::ptime end_time=boost::posix_time::microsec_clock::local_time();
772
 
  session->status_var.execution_time_nsec+=(end_time-start_time).total_microseconds();
 
2562
  return(error);
773
2563
}
774
2564
 
775
2565
 
788
2578
                       Item *default_value, Item *on_update_value,
789
2579
                       LEX_STRING *comment,
790
2580
                       char *change,
791
 
                       List<String> *interval_list, const CHARSET_INFO * const cs)
 
2581
                       List<String> *interval_list, const CHARSET_INFO * const cs,
 
2582
                       virtual_column_info *vcol_info)
792
2583
{
793
 
  register CreateField *new_field;
 
2584
  register Create_field *new_field;
794
2585
  LEX  *lex= session->lex;
795
 
  statement::AlterTable *statement= (statement::AlterTable *)lex->statement;
796
2586
 
797
2587
  if (check_identifier_name(field_name, ER_TOO_LONG_IDENT))
798
 
    return true;
 
2588
    return(1);                          /* purecov: inspected */
799
2589
 
800
2590
  if (type_modifier & PRI_KEY_FLAG)
801
2591
  {
804
2594
    key= new Key(Key::PRIMARY, null_lex_str,
805
2595
                      &default_key_create_info,
806
2596
                      0, lex->col_list);
807
 
    statement->alter_info.key_list.push_back(key);
 
2597
    lex->alter_info.key_list.push_back(key);
808
2598
    lex->col_list.empty();
809
2599
  }
810
2600
  if (type_modifier & (UNIQUE_FLAG | UNIQUE_KEY_FLAG))
814
2604
    key= new Key(Key::UNIQUE, null_lex_str,
815
2605
                 &default_key_create_info, 0,
816
2606
                 lex->col_list);
817
 
    statement->alter_info.key_list.push_back(key);
 
2607
    lex->alter_info.key_list.push_back(key);
818
2608
    lex->col_list.empty();
819
2609
  }
820
2610
 
832
2622
         type == DRIZZLE_TYPE_TIMESTAMP))
833
2623
    {
834
2624
      my_error(ER_INVALID_DEFAULT, MYF(0), field_name->str);
835
 
      return true;
 
2625
      return(1);
836
2626
    }
837
2627
    else if (default_value->type() == Item::NULL_ITEM)
838
2628
    {
841
2631
          NOT_NULL_FLAG)
842
2632
      {
843
2633
        my_error(ER_INVALID_DEFAULT, MYF(0), field_name->str);
844
 
        return true;
 
2634
        return(1);
845
2635
      }
846
2636
    }
847
2637
    else if (type_modifier & AUTO_INCREMENT_FLAG)
848
2638
    {
849
2639
      my_error(ER_INVALID_DEFAULT, MYF(0), field_name->str);
850
 
      return true;
 
2640
      return(1);
851
2641
    }
852
2642
  }
853
2643
 
854
2644
  if (on_update_value && type != DRIZZLE_TYPE_TIMESTAMP)
855
2645
  {
856
2646
    my_error(ER_INVALID_ON_UPDATE, MYF(0), field_name->str);
857
 
    return true;
 
2647
    return(1);
858
2648
  }
859
2649
 
860
 
  if (!(new_field= new CreateField()) ||
 
2650
  if (!(new_field= new Create_field()) ||
861
2651
      new_field->init(session, field_name->str, type, length, decimals, type_modifier,
862
2652
                      default_value, on_update_value, comment, change,
863
 
                      interval_list, cs, 0, column_format))
864
 
    return true;
 
2653
                      interval_list, cs, 0, column_format,
 
2654
                      vcol_info))
 
2655
    return(1);
865
2656
 
866
 
  statement->alter_info.create_list.push_back(new_field);
 
2657
  lex->alter_info.create_list.push_back(new_field);
867
2658
  lex->last_field=new_field;
868
 
 
869
 
  return false;
 
2659
  return(0);
870
2660
}
871
2661
 
872
2662
 
877
2667
  current_session->lex->last_field->after=const_cast<char*> (name);
878
2668
}
879
2669
 
 
2670
bool
 
2671
add_proc_to_list(Session* session, Item *item)
 
2672
{
 
2673
  order_st *order;
 
2674
  Item  **item_ptr;
 
2675
 
 
2676
  if (!(order = (order_st *) session->alloc(sizeof(order_st)+sizeof(Item*))))
 
2677
    return 1;
 
2678
  item_ptr = (Item**) (order+1);
 
2679
  *item_ptr= item;
 
2680
  order->item=item_ptr;
 
2681
  order->free_me=0;
 
2682
  session->lex->proc_list.link_in_list((unsigned char*) order,(unsigned char**) &order->next);
 
2683
  return 0;
 
2684
}
 
2685
 
 
2686
 
 
2687
/**
 
2688
  save order by and tables in own lists.
 
2689
*/
 
2690
 
 
2691
bool add_to_list(Session *session, SQL_LIST &list,Item *item,bool asc)
 
2692
{
 
2693
  order_st *order;
 
2694
  if (!(order = (order_st *) session->alloc(sizeof(order_st))))
 
2695
    return(1);
 
2696
  order->item_ptr= item;
 
2697
  order->item= &order->item_ptr;
 
2698
  order->asc = asc;
 
2699
  order->free_me=0;
 
2700
  order->used=0;
 
2701
  order->counter_used= 0;
 
2702
  list.link_in_list((unsigned char*) order,(unsigned char**) &order->next);
 
2703
  return(0);
 
2704
}
 
2705
 
 
2706
 
880
2707
/**
881
2708
  Add a table to list of used tables.
882
2709
 
896
2723
    \#  Pointer to TableList element added to the total table list
897
2724
*/
898
2725
 
899
 
TableList *Select_Lex::add_table_to_list(Session *session,
900
 
                                                             Table_ident *table,
901
 
                                                             LEX_STRING *alias,
902
 
                                                             const bitset<NUM_OF_TABLE_OPTIONS>& table_options,
903
 
                                                             thr_lock_type lock_type,
904
 
                                                             List<Index_hint> *index_hints_arg,
905
 
                                         LEX_STRING *option)
 
2726
TableList *st_select_lex::add_table_to_list(Session *session,
 
2727
                                             Table_ident *table,
 
2728
                                             LEX_STRING *alias,
 
2729
                                             uint32_t table_options,
 
2730
                                             thr_lock_type lock_type,
 
2731
                                             List<Index_hint> *index_hints_arg,
 
2732
                                             LEX_STRING *option)
906
2733
{
907
 
  TableList *ptr;
 
2734
  register TableList *ptr;
908
2735
  TableList *previous_table_ref; /* The table preceding the current one. */
909
2736
  char *alias_str;
910
2737
  LEX *lex= session->lex;
911
2738
 
912
2739
  if (!table)
913
 
    return NULL;                                // End of memory
 
2740
    return(0);                          // End of memory
914
2741
  alias_str= alias ? alias->str : table->table.str;
915
 
  if (! table_options.test(TL_OPTION_ALIAS) &&
 
2742
  if (!test(table_options & TL_OPTION_ALIAS) &&
916
2743
      check_table_name(table->table.str, table->table.length))
917
2744
  {
918
2745
    my_error(ER_WRONG_TABLE_NAME, MYF(0), table->table.str);
919
 
    return NULL;
 
2746
    return(0);
920
2747
  }
921
2748
 
922
 
  if (table->is_derived_table() == false && table->db.str)
 
2749
  if (table->is_derived_table() == false && table->db.str &&
 
2750
      check_db_name(&table->db))
923
2751
  {
924
 
    my_casedn_str(files_charset_info, table->db.str);
925
 
 
926
 
    SchemaIdentifier schema_identifier(string(table->db.str));
927
 
    if (not check_db_name(session, schema_identifier))
928
 
    {
929
 
 
930
 
      my_error(ER_WRONG_DB_NAME, MYF(0), table->db.str);
931
 
      return NULL;
932
 
    }
 
2752
    my_error(ER_WRONG_DB_NAME, MYF(0), table->db.str);
 
2753
    return(0);
933
2754
  }
934
2755
 
935
2756
  if (!alias)                                   /* Alias is case sensitive */
938
2759
    {
939
2760
      my_message(ER_DERIVED_MUST_HAVE_ALIAS,
940
2761
                 ER(ER_DERIVED_MUST_HAVE_ALIAS), MYF(0));
941
 
      return NULL;
 
2762
      return(0);
942
2763
    }
943
2764
    if (!(alias_str= (char*) session->memdup(alias_str,table->table.length+1)))
944
 
      return NULL;
 
2765
      return(0);
945
2766
  }
946
2767
  if (!(ptr = (TableList *) session->calloc(sizeof(TableList))))
947
 
    return NULL;
948
 
 
 
2768
    return(0);                          /* purecov: inspected */
949
2769
  if (table->db.str)
950
2770
  {
951
 
    ptr->setIsFqtn(true);
952
 
    ptr->setSchemaName(table->db.str);
 
2771
    ptr->is_fqtn= true;
 
2772
    ptr->db= table->db.str;
953
2773
    ptr->db_length= table->db.length;
954
2774
  }
955
 
  else if (lex->copy_db_to(ptr->getSchemaNamePtr(), &ptr->db_length))
956
 
    return NULL;
 
2775
  else if (lex->copy_db_to(&ptr->db, &ptr->db_length))
 
2776
    return(0);
957
2777
  else
958
 
    ptr->setIsFqtn(false);
 
2778
    ptr->is_fqtn= false;
959
2779
 
960
2780
  ptr->alias= alias_str;
961
 
  ptr->setIsAlias(alias ? true : false);
962
 
  ptr->setTableName(table->table.str);
 
2781
  ptr->is_alias= alias ? true : false;
 
2782
  if (lower_case_table_names && table->table.length)
 
2783
    table->table.length= my_casedn_str(files_charset_info, table->table.str);
 
2784
  ptr->table_name=table->table.str;
963
2785
  ptr->table_name_length=table->table.length;
964
2786
  ptr->lock_type=   lock_type;
965
 
  ptr->force_index= table_options.test(TL_OPTION_FORCE_INDEX);
966
 
  ptr->ignore_leaves= table_options.test(TL_OPTION_IGNORE_LEAVES);
 
2787
  ptr->lock_timeout= -1;      /* default timeout */
 
2788
  ptr->lock_transactional= 1; /* allow transactional locks */
 
2789
  ptr->updating=    test(table_options & TL_OPTION_UPDATING);
 
2790
  ptr->force_index= test(table_options & TL_OPTION_FORCE_INDEX);
 
2791
  ptr->ignore_leaves= test(table_options & TL_OPTION_IGNORE_LEAVES);
967
2792
  ptr->derived=     table->sel;
 
2793
  if (!ptr->derived && !my_strcasecmp(system_charset_info, ptr->db,
 
2794
                                      INFORMATION_SCHEMA_NAME.c_str()))
 
2795
  {
 
2796
    ST_SCHEMA_TABLE *schema_table= find_schema_table(session, ptr->table_name);
 
2797
    if (!schema_table ||
 
2798
        (schema_table->hidden &&
 
2799
         ((sql_command_flags[lex->sql_command].test(CF_BIT_STATUS_COMMAND)) == 0 ||
 
2800
          /*
 
2801
            this check is used for show columns|keys from I_S hidden table
 
2802
          */
 
2803
          lex->sql_command == SQLCOM_SHOW_FIELDS ||
 
2804
          lex->sql_command == SQLCOM_SHOW_KEYS)))
 
2805
    {
 
2806
      my_error(ER_UNKNOWN_TABLE, MYF(0),
 
2807
               ptr->table_name, INFORMATION_SCHEMA_NAME.c_str());
 
2808
      return(0);
 
2809
    }
 
2810
    ptr->schema_table_name= ptr->table_name;
 
2811
    ptr->schema_table= schema_table;
 
2812
  }
968
2813
  ptr->select_lex=  lex->current_select;
 
2814
  ptr->cacheable_table= 1;
969
2815
  ptr->index_hints= index_hints_arg;
970
2816
  ptr->option= option ? option->str : 0;
971
2817
  /* check that used name is unique */
977
2823
         tables=tables->next_local)
978
2824
    {
979
2825
      if (!my_strcasecmp(table_alias_charset, alias_str, tables->alias) &&
980
 
          !strcasecmp(ptr->getSchemaName(), tables->getSchemaName()))
 
2826
          !strcmp(ptr->db, tables->db))
981
2827
      {
982
 
        my_error(ER_NONUNIQ_TABLE, MYF(0), alias_str);
983
 
        return NULL;
 
2828
        my_error(ER_NONUNIQ_TABLE, MYF(0), alias_str); /* purecov: tested */
 
2829
        return(0);                              /* purecov: tested */
984
2830
      }
985
2831
    }
986
2832
  }
1015
2861
  ptr->next_name_resolution_table= NULL;
1016
2862
  /* Link table in global list (all used tables) */
1017
2863
  lex->add_to_query_tables(ptr);
1018
 
  return ptr;
 
2864
  return(ptr);
1019
2865
}
1020
2866
 
1021
2867
 
1025
2871
    The function initializes a structure of the TableList type
1026
2872
    for a nested join. It sets up its nested join list as empty.
1027
2873
    The created structure is added to the front of the current
1028
 
    join list in the Select_Lex object. Then the function
 
2874
    join list in the st_select_lex object. Then the function
1029
2875
    changes the current nest level for joins to refer to the newly
1030
2876
    created empty list after having saved the info on the old level
1031
2877
    in the initialized structure.
1038
2884
    1   otherwise
1039
2885
*/
1040
2886
 
1041
 
bool Select_Lex::init_nested_join(Session *session)
 
2887
bool st_select_lex::init_nested_join(Session *session)
1042
2888
{
1043
2889
  TableList *ptr;
1044
2890
  nested_join_st *nested_join;
1045
2891
 
1046
2892
  if (!(ptr= (TableList*) session->calloc(ALIGN_SIZE(sizeof(TableList))+
1047
2893
                                       sizeof(nested_join_st))))
1048
 
    return true;
1049
 
  ptr->setNestedJoin(((nested_join_st*) ((unsigned char*) ptr + ALIGN_SIZE(sizeof(TableList)))));
1050
 
  nested_join= ptr->getNestedJoin();
 
2894
    return(1);
 
2895
  nested_join= ptr->nested_join=
 
2896
    ((nested_join_st*) ((unsigned char*) ptr + ALIGN_SIZE(sizeof(TableList))));
 
2897
 
1051
2898
  join_list->push_front(ptr);
1052
 
  ptr->setEmbedding(embedding);
1053
 
  ptr->setJoinList(join_list);
 
2899
  ptr->embedding= embedding;
 
2900
  ptr->join_list= join_list;
1054
2901
  ptr->alias= (char*) "(nested_join)";
1055
2902
  embedding= ptr;
1056
2903
  join_list= &nested_join->join_list;
1057
2904
  join_list->empty();
1058
 
  return false;
 
2905
  return(0);
1059
2906
}
1060
2907
 
1061
2908
 
1073
2920
    - 0, otherwise
1074
2921
*/
1075
2922
 
1076
 
TableList *Select_Lex::end_nested_join(Session *)
 
2923
TableList *st_select_lex::end_nested_join(Session *)
1077
2924
{
1078
2925
  TableList *ptr;
1079
2926
  nested_join_st *nested_join;
1080
2927
 
1081
2928
  assert(embedding);
1082
2929
  ptr= embedding;
1083
 
  join_list= ptr->getJoinList();
1084
 
  embedding= ptr->getEmbedding();
1085
 
  nested_join= ptr->getNestedJoin();
 
2930
  join_list= ptr->join_list;
 
2931
  embedding= ptr->embedding;
 
2932
  nested_join= ptr->nested_join;
1086
2933
  if (nested_join->join_list.elements == 1)
1087
2934
  {
1088
2935
    TableList *embedded= nested_join->join_list.head();
1089
2936
    join_list->pop();
1090
 
    embedded->setJoinList(join_list);
1091
 
    embedded->setEmbedding(embedding);
 
2937
    embedded->join_list= join_list;
 
2938
    embedded->embedding= embedding;
1092
2939
    join_list->push_front(embedded);
1093
2940
    ptr= embedded;
1094
2941
  }
1095
2942
  else if (nested_join->join_list.elements == 0)
1096
2943
  {
1097
2944
    join_list->pop();
1098
 
    ptr= NULL;                                     // return value
 
2945
    ptr= 0;                                     // return value
1099
2946
  }
1100
 
  return ptr;
 
2947
  return(ptr);
1101
2948
}
1102
2949
 
1103
2950
 
1114
2961
    \#  Pointer to TableList element created for the new nested join
1115
2962
*/
1116
2963
 
1117
 
TableList *Select_Lex::nest_last_join(Session *session)
 
2964
TableList *st_select_lex::nest_last_join(Session *session)
1118
2965
{
1119
2966
  TableList *ptr;
1120
2967
  nested_join_st *nested_join;
1121
2968
  List<TableList> *embedded_list;
1122
2969
 
1123
2970
  if (!(ptr= (TableList*) session->calloc(ALIGN_SIZE(sizeof(TableList))+
1124
 
                                          sizeof(nested_join_st))))
1125
 
    return NULL;
1126
 
  ptr->setNestedJoin(((nested_join_st*) ((unsigned char*) ptr + ALIGN_SIZE(sizeof(TableList)))));
1127
 
  nested_join= ptr->getNestedJoin();
1128
 
  ptr->setEmbedding(embedding);
1129
 
  ptr->setJoinList(join_list);
 
2971
                                       sizeof(nested_join_st))))
 
2972
    return(0);
 
2973
  nested_join= ptr->nested_join=
 
2974
    ((nested_join_st*) ((unsigned char*) ptr + ALIGN_SIZE(sizeof(TableList))));
 
2975
 
 
2976
  ptr->embedding= embedding;
 
2977
  ptr->join_list= join_list;
1130
2978
  ptr->alias= (char*) "(nest_last_join)";
1131
2979
  embedded_list= &nested_join->join_list;
1132
2980
  embedded_list->empty();
1134
2982
  for (uint32_t i=0; i < 2; i++)
1135
2983
  {
1136
2984
    TableList *table= join_list->pop();
1137
 
    table->setJoinList(embedded_list);
1138
 
    table->setEmbedding(ptr);
 
2985
    table->join_list= embedded_list;
 
2986
    table->embedding= ptr;
1139
2987
    embedded_list->push_back(table);
1140
2988
    if (table->natural_join)
1141
2989
    {
1150
2998
  }
1151
2999
  join_list->push_front(ptr);
1152
3000
  nested_join->used_tables= nested_join->not_null_tables= (table_map) 0;
1153
 
  return ptr;
 
3001
  return(ptr);
1154
3002
}
1155
3003
 
1156
3004
 
1158
3006
  Add a table to the current join list.
1159
3007
 
1160
3008
    The function puts a table in front of the current join list
1161
 
    of Select_Lex object.
 
3009
    of st_select_lex object.
1162
3010
    Thus, joined tables are put into this list in the reverse order
1163
3011
    (the most outer join operation follows first).
1164
3012
 
1168
3016
    None
1169
3017
*/
1170
3018
 
1171
 
void Select_Lex::add_joined_table(TableList *table)
 
3019
void st_select_lex::add_joined_table(TableList *table)
1172
3020
{
1173
3021
  join_list->push_front(table);
1174
 
  table->setJoinList(join_list);
1175
 
  table->setEmbedding(embedding);
 
3022
  table->join_list= join_list;
 
3023
  table->embedding= embedding;
 
3024
  return;
1176
3025
}
1177
3026
 
1178
3027
 
1207
3056
    - 0, otherwise
1208
3057
*/
1209
3058
 
1210
 
TableList *Select_Lex::convert_right_join()
 
3059
TableList *st_select_lex::convert_right_join()
1211
3060
{
1212
3061
  TableList *tab2= join_list->pop();
1213
3062
  TableList *tab1= join_list->pop();
1216
3065
  join_list->push_front(tab1);
1217
3066
  tab1->outer_join|= JOIN_TYPE_RIGHT;
1218
3067
 
1219
 
  return tab1;
 
3068
  return(tab1);
1220
3069
}
1221
3070
 
1222
3071
/**
1230
3079
    query
1231
3080
*/
1232
3081
 
1233
 
void Select_Lex::set_lock_for_tables(thr_lock_type lock_type)
 
3082
void st_select_lex::set_lock_for_tables(thr_lock_type lock_type)
1234
3083
{
 
3084
  bool for_update= lock_type >= TL_READ_NO_INSERT;
 
3085
 
1235
3086
  for (TableList *tables= (TableList*) table_list.first;
1236
3087
       tables;
1237
3088
       tables= tables->next_local)
1238
3089
  {
1239
3090
    tables->lock_type= lock_type;
 
3091
    tables->updating=  for_update;
1240
3092
  }
 
3093
  return;
1241
3094
}
1242
3095
 
1243
3096
 
1244
3097
/**
1245
 
  Create a fake Select_Lex for a unit.
 
3098
  Create a fake SELECT_LEX for a unit.
1246
3099
 
1247
 
    The method create a fake Select_Lex object for a unit.
 
3100
    The method create a fake SELECT_LEX object for a unit.
1248
3101
    This object is created for any union construct containing a union
1249
3102
    operation and also for any single select union construct of the form
1250
3103
    @verbatim
1251
 
    (SELECT ... ORDER BY order_list [LIMIT n]) ORDER BY ...
 
3104
    (SELECT ... order_st BY order_list [LIMIT n]) order_st BY ...
1252
3105
    @endvarbatim
1253
3106
    or of the form
1254
3107
    @varbatim
1255
 
    (SELECT ... ORDER BY LIMIT n) ORDER BY ...
 
3108
    (SELECT ... order_st BY LIMIT n) order_st BY ...
1256
3109
    @endvarbatim
1257
3110
 
1258
3111
  @param session_arg               thread handle
1267
3120
    0     on success
1268
3121
*/
1269
3122
 
1270
 
bool Select_Lex_Unit::add_fake_select_lex(Session *session_arg)
 
3123
bool st_select_lex_unit::add_fake_select_lex(Session *session_arg)
1271
3124
{
1272
 
  Select_Lex *first_sl= first_select();
 
3125
  SELECT_LEX *first_sl= first_select();
1273
3126
  assert(!fake_select_lex);
1274
3127
 
1275
 
  if (!(fake_select_lex= new (session_arg->mem_root) Select_Lex()))
 
3128
  if (!(fake_select_lex= new (session_arg->mem_root) SELECT_LEX()))
1276
3129
      return(1);
1277
3130
  fake_select_lex->include_standalone(this,
1278
 
                                      (Select_Lex_Node**)&fake_select_lex);
 
3131
                                      (SELECT_LEX_NODE**)&fake_select_lex);
1279
3132
  fake_select_lex->select_number= INT_MAX;
1280
3133
  fake_select_lex->parent_lex= session_arg->lex; /* Used in init_query. */
1281
3134
  fake_select_lex->make_empty_select();
1283
3136
  fake_select_lex->select_limit= 0;
1284
3137
 
1285
3138
  fake_select_lex->context.outer_context=first_sl->context.outer_context;
1286
 
  /* allow item list resolving in fake select for ORDER BY */
 
3139
  /* allow item list resolving in fake select for order_st BY */
1287
3140
  fake_select_lex->context.resolve_in_select_list= true;
1288
3141
  fake_select_lex->context.select_lex= fake_select_lex;
1289
3142
 
1291
3144
  {
1292
3145
    /*
1293
3146
      This works only for
1294
 
      (SELECT ... ORDER BY list [LIMIT n]) ORDER BY order_list [LIMIT m],
1295
 
      (SELECT ... LIMIT n) ORDER BY order_list [LIMIT m]
 
3147
      (SELECT ... order_st BY list [LIMIT n]) order_st BY order_list [LIMIT m],
 
3148
      (SELECT ... LIMIT n) order_st BY order_list [LIMIT m]
1296
3149
      just before the parser starts processing order_list
1297
3150
    */
1298
3151
    global_parameters= fake_select_lex;
1407
3260
*/
1408
3261
 
1409
3262
void add_join_natural(TableList *a, TableList *b, List<String> *using_fields,
1410
 
                      Select_Lex *lex)
 
3263
                      SELECT_LEX *lex)
1411
3264
{
1412
3265
  b->natural_join= a;
1413
3266
  lex->prev_join_using= using_fields;
1415
3268
 
1416
3269
 
1417
3270
/**
 
3271
  Reload/resets privileges and the different caches.
 
3272
 
 
3273
  @param session Thread handler (can be NULL!)
 
3274
  @param options What should be reset/reloaded (tables, privileges, slave...)
 
3275
  @param tables Tables to flush (if any)
 
3276
  @param write_to_binlog True if we can write to the binlog.
 
3277
 
 
3278
  @note Depending on 'options', it may be very bad to write the
 
3279
    query to the binlog (e.g. FLUSH SLAVE); this is a
 
3280
    pointer where reload_cache() will put 0 if
 
3281
    it thinks we really should not write to the binlog.
 
3282
    Otherwise it will put 1.
 
3283
 
 
3284
  @return Error status code
 
3285
    @retval 0 Ok
 
3286
    @retval !=0  Error; session->killed is set or session->is_error() is true
 
3287
*/
 
3288
 
 
3289
bool reload_cache(Session *session, ulong options, TableList *tables,
 
3290
                          bool *write_to_binlog)
 
3291
{
 
3292
  bool result=0;
 
3293
  select_errors=0;                              /* Write if more errors */
 
3294
  bool tmp_write_to_binlog= 1;
 
3295
 
 
3296
  if (options & REFRESH_LOG)
 
3297
  {
 
3298
    /*
 
3299
      Flush the normal query log, the update log, the binary log,
 
3300
      the slow query log, the relay log (if it exists) and the log
 
3301
      tables.
 
3302
    */
 
3303
 
 
3304
    /*
 
3305
      Writing this command to the binlog may result in infinite loops
 
3306
      when doing mysqlbinlog|mysql, and anyway it does not really make
 
3307
      sense to log it automatically (would cause more trouble to users
 
3308
      than it would help them)
 
3309
    */
 
3310
    tmp_write_to_binlog= 0;
 
3311
    if (drizzle_bin_log.is_open())
 
3312
    {
 
3313
      drizzle_bin_log.rotate_and_purge(RP_FORCE_ROTATE);
 
3314
    }
 
3315
    pthread_mutex_lock(&LOCK_active_mi);
 
3316
    rotate_relay_log(active_mi);
 
3317
    pthread_mutex_unlock(&LOCK_active_mi);
 
3318
 
 
3319
    if (ha_flush_logs(NULL))
 
3320
      result=1;
 
3321
  }
 
3322
  /*
 
3323
    Note that if REFRESH_READ_LOCK bit is set then REFRESH_TABLES is set too
 
3324
    (see sql_yacc.yy)
 
3325
  */
 
3326
  if (options & (REFRESH_TABLES | REFRESH_READ_LOCK))
 
3327
  {
 
3328
    if ((options & REFRESH_READ_LOCK) && session)
 
3329
    {
 
3330
      /*
 
3331
        We must not try to aspire a global read lock if we have a write
 
3332
        locked table. This would lead to a deadlock when trying to
 
3333
        reopen (and re-lock) the table after the flush.
 
3334
      */
 
3335
      if (session->locked_tables)
 
3336
      {
 
3337
        THR_LOCK_DATA **lock_p= session->locked_tables->locks;
 
3338
        THR_LOCK_DATA **end_p= lock_p + session->locked_tables->lock_count;
 
3339
 
 
3340
        for (; lock_p < end_p; lock_p++)
 
3341
        {
 
3342
          if ((*lock_p)->type >= TL_WRITE_ALLOW_WRITE)
 
3343
          {
 
3344
            my_error(ER_LOCK_OR_ACTIVE_TRANSACTION, MYF(0));
 
3345
            return 1;
 
3346
          }
 
3347
        }
 
3348
      }
 
3349
      /*
 
3350
        Writing to the binlog could cause deadlocks, as we don't log
 
3351
        UNLOCK TABLES
 
3352
      */
 
3353
      tmp_write_to_binlog= 0;
 
3354
      if (lock_global_read_lock(session))
 
3355
        return 1;                               // Killed
 
3356
      result= close_cached_tables(session, tables, false, (options & REFRESH_FAST) ?
 
3357
                                  false : true, true);
 
3358
      if (make_global_read_lock_block_commit(session)) // Killed
 
3359
      {
 
3360
        /* Don't leave things in a half-locked state */
 
3361
        unlock_global_read_lock(session);
 
3362
        return 1;
 
3363
      }
 
3364
    }
 
3365
    else
 
3366
      result= close_cached_tables(session, tables, false, (options & REFRESH_FAST) ?
 
3367
                                  false : true, false);
 
3368
    my_dbopt_cleanup();
 
3369
  }
 
3370
  if (session && (options & REFRESH_STATUS))
 
3371
    refresh_status(session);
 
3372
  if (options & REFRESH_MASTER)
 
3373
  {
 
3374
    assert(session);
 
3375
    tmp_write_to_binlog= 0;
 
3376
    if (reset_master(session))
 
3377
    {
 
3378
      result=1;
 
3379
    }
 
3380
  }
 
3381
 if (options & REFRESH_SLAVE)
 
3382
 {
 
3383
   tmp_write_to_binlog= 0;
 
3384
   pthread_mutex_lock(&LOCK_active_mi);
 
3385
   if (reset_slave(session, active_mi))
 
3386
     result=1;
 
3387
   pthread_mutex_unlock(&LOCK_active_mi);
 
3388
 }
 
3389
 *write_to_binlog= tmp_write_to_binlog;
 
3390
 return result;
 
3391
}
 
3392
 
 
3393
 
 
3394
/**
 
3395
  kill on thread.
 
3396
 
 
3397
  @param session                        Thread class
 
3398
  @param id                     Thread id
 
3399
  @param only_kill_query        Should it kill the query or the connection
 
3400
 
 
3401
  @note
 
3402
    This is written such that we have a short lock on LOCK_thread_count
 
3403
*/
 
3404
 
 
3405
static unsigned int
 
3406
kill_one_thread(Session *, ulong id, bool only_kill_query)
 
3407
{
 
3408
  Session *tmp;
 
3409
  uint32_t error=ER_NO_SUCH_THREAD;
 
3410
  pthread_mutex_lock(&LOCK_thread_count); // For unlink from list
 
3411
  I_List_iterator<Session> it(threads);
 
3412
  while ((tmp=it++))
 
3413
  {
 
3414
    if (tmp->command == COM_DAEMON)
 
3415
      continue;
 
3416
    if (tmp->thread_id == id)
 
3417
    {
 
3418
      pthread_mutex_lock(&tmp->LOCK_delete);    // Lock from delete
 
3419
      break;
 
3420
    }
 
3421
  }
 
3422
  pthread_mutex_unlock(&LOCK_thread_count);
 
3423
  if (tmp)
 
3424
  {
 
3425
    tmp->awake(only_kill_query ? Session::KILL_QUERY : Session::KILL_CONNECTION);
 
3426
    error=0;
 
3427
    pthread_mutex_unlock(&tmp->LOCK_delete);
 
3428
  }
 
3429
  return(error);
 
3430
}
 
3431
 
 
3432
 
 
3433
/*
 
3434
  kills a thread and sends response
 
3435
 
 
3436
  SYNOPSIS
 
3437
    sql_kill()
 
3438
    session                     Thread class
 
3439
    id                  Thread id
 
3440
    only_kill_query     Should it kill the query or the connection
 
3441
*/
 
3442
 
 
3443
void sql_kill(Session *session, ulong id, bool only_kill_query)
 
3444
{
 
3445
  uint32_t error;
 
3446
  if (!(error= kill_one_thread(session, id, only_kill_query)))
 
3447
    my_ok(session);
 
3448
  else
 
3449
    my_error(error, MYF(0), id);
 
3450
}
 
3451
 
 
3452
 
 
3453
/** If pointer is not a null pointer, append filename to it. */
 
3454
 
 
3455
bool append_file_to_dir(Session *session, const char **filename_ptr,
 
3456
                        const char *table_name)
 
3457
{
 
3458
  char buff[FN_REFLEN],*ptr, *end;
 
3459
  if (!*filename_ptr)
 
3460
    return 0;                                   // nothing to do
 
3461
 
 
3462
  /* Check that the filename is not too long and it's a hard path */
 
3463
  if (strlen(*filename_ptr)+strlen(table_name) >= FN_REFLEN-1 ||
 
3464
      !test_if_hard_path(*filename_ptr))
 
3465
  {
 
3466
    my_error(ER_WRONG_TABLE_NAME, MYF(0), *filename_ptr);
 
3467
    return 1;
 
3468
  }
 
3469
  /* Fix is using unix filename format on dos */
 
3470
  strcpy(buff,*filename_ptr);
 
3471
  end=convert_dirname(buff, *filename_ptr, NULL);
 
3472
  if (!(ptr= (char*) session->alloc((size_t) (end-buff) + strlen(table_name)+1)))
 
3473
    return 1;                                   // End of memory
 
3474
  *filename_ptr=ptr;
 
3475
  sprintf(ptr,"%s%s",buff,table_name);
 
3476
  return 0;
 
3477
}
 
3478
 
 
3479
 
 
3480
/**
1418
3481
  Check if the select is a simple select (not an union).
1419
3482
 
1420
3483
  @retval
1432
3495
    char command[80];
1433
3496
    Lex_input_stream *lip= session->m_lip;
1434
3497
    strncpy(command, lip->yylval->symbol.str,
1435
 
            min(lip->yylval->symbol.length, (uint32_t)(sizeof(command)-1)));
1436
 
    command[min(lip->yylval->symbol.length, (uint32_t)(sizeof(command)-1))]=0;
 
3498
            cmin(lip->yylval->symbol.length, sizeof(command)-1));
 
3499
    command[cmin(lip->yylval->symbol.length, sizeof(command)-1)]=0;
1437
3500
    my_error(ER_CANT_USE_OPTION_HERE, MYF(0), command);
1438
3501
    return 1;
1439
3502
  }
1455
3518
Item * all_any_subquery_creator(Item *left_expr,
1456
3519
                                chooser_compare_func_creator cmp,
1457
3520
                                bool all,
1458
 
                                Select_Lex *select_lex)
 
3521
                                SELECT_LEX *select_lex)
1459
3522
{
1460
3523
  if ((cmp == &comp_eq_creator) && !all)       //  = ANY <=> IN
1461
3524
    return new Item_in_subselect(left_expr, select_lex);
1473
3536
 
1474
3537
 
1475
3538
/**
1476
 
  Update query pre-check.
 
3539
  Multi update query pre-check.
1477
3540
 
1478
3541
  @param session                Thread handler
1479
3542
  @param tables Global/local table list (have to be the same)
1484
3547
    true  Error
1485
3548
*/
1486
3549
 
 
3550
bool multi_update_precheck(Session *session, TableList *)
 
3551
{
 
3552
  const char *msg= 0;
 
3553
  LEX *lex= session->lex;
 
3554
  SELECT_LEX *select_lex= &lex->select_lex;
 
3555
 
 
3556
  if (select_lex->item_list.elements != lex->value_list.elements)
 
3557
  {
 
3558
    my_message(ER_WRONG_VALUE_COUNT, ER(ER_WRONG_VALUE_COUNT), MYF(0));
 
3559
    return(true);
 
3560
  }
 
3561
 
 
3562
  if (select_lex->order_list.elements)
 
3563
    msg= "ORDER BY";
 
3564
  else if (select_lex->select_limit)
 
3565
    msg= "LIMIT";
 
3566
  if (msg)
 
3567
  {
 
3568
    my_error(ER_WRONG_USAGE, MYF(0), "UPDATE", msg);
 
3569
    return(true);
 
3570
  }
 
3571
  return(false);
 
3572
}
 
3573
 
 
3574
/**
 
3575
  Multi delete query pre-check.
 
3576
 
 
3577
  @param session                        Thread handler
 
3578
  @param tables         Global/local table list
 
3579
 
 
3580
  @retval
 
3581
    false OK
 
3582
  @retval
 
3583
    true  error
 
3584
*/
 
3585
 
 
3586
bool multi_delete_precheck(Session *session, TableList *)
 
3587
{
 
3588
  SELECT_LEX *select_lex= &session->lex->select_lex;
 
3589
  TableList **save_query_tables_own_last= session->lex->query_tables_own_last;
 
3590
 
 
3591
  session->lex->query_tables_own_last= 0;
 
3592
  session->lex->query_tables_own_last= save_query_tables_own_last;
 
3593
 
 
3594
  if ((session->options & OPTION_SAFE_UPDATES) && !select_lex->where)
 
3595
  {
 
3596
    my_message(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE,
 
3597
               ER(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE), MYF(0));
 
3598
    return(true);
 
3599
  }
 
3600
  return(false);
 
3601
}
 
3602
 
 
3603
 
 
3604
/*
 
3605
  Given a table in the source list, find a correspondent table in the
 
3606
  table references list.
 
3607
 
 
3608
  @param lex Pointer to LEX representing multi-delete.
 
3609
  @param src Source table to match.
 
3610
  @param ref Table references list.
 
3611
 
 
3612
  @remark The source table list (tables listed before the FROM clause
 
3613
  or tables listed in the FROM clause before the USING clause) may
 
3614
  contain table names or aliases that must match unambiguously one,
 
3615
  and only one, table in the target table list (table references list,
 
3616
  after FROM/USING clause).
 
3617
 
 
3618
  @return Matching table, NULL otherwise.
 
3619
*/
 
3620
 
 
3621
static TableList *multi_delete_table_match(LEX *, TableList *tbl,
 
3622
                                           TableList *tables)
 
3623
{
 
3624
  TableList *match= NULL;
 
3625
 
 
3626
  for (TableList *elem= tables; elem; elem= elem->next_local)
 
3627
  {
 
3628
    int cmp;
 
3629
 
 
3630
    if (tbl->is_fqtn && elem->is_alias)
 
3631
      continue; /* no match */
 
3632
    if (tbl->is_fqtn && elem->is_fqtn)
 
3633
      cmp= my_strcasecmp(table_alias_charset, tbl->table_name, elem->table_name) ||
 
3634
           strcmp(tbl->db, elem->db);
 
3635
    else if (elem->is_alias)
 
3636
      cmp= my_strcasecmp(table_alias_charset, tbl->alias, elem->alias);
 
3637
    else
 
3638
      cmp= my_strcasecmp(table_alias_charset, tbl->table_name, elem->table_name) ||
 
3639
           strcmp(tbl->db, elem->db);
 
3640
 
 
3641
    if (cmp)
 
3642
      continue;
 
3643
 
 
3644
    if (match)
 
3645
    {
 
3646
      my_error(ER_NONUNIQ_TABLE, MYF(0), elem->alias);
 
3647
      return(NULL);
 
3648
    }
 
3649
 
 
3650
    match= elem;
 
3651
  }
 
3652
 
 
3653
  if (!match)
 
3654
    my_error(ER_UNKNOWN_TABLE, MYF(0), tbl->table_name, "MULTI DELETE");
 
3655
 
 
3656
  return(match);
 
3657
}
 
3658
 
 
3659
 
 
3660
/**
 
3661
  Link tables in auxilary table list of multi-delete with corresponding
 
3662
  elements in main table list, and set proper locks for them.
 
3663
 
 
3664
  @param lex   pointer to LEX representing multi-delete
 
3665
 
 
3666
  @retval
 
3667
    false   success
 
3668
  @retval
 
3669
    true    error
 
3670
*/
 
3671
 
 
3672
bool multi_delete_set_locks_and_link_aux_tables(LEX *lex)
 
3673
{
 
3674
  TableList *tables= (TableList*)lex->select_lex.table_list.first;
 
3675
  TableList *target_tbl;
 
3676
 
 
3677
  lex->table_count= 0;
 
3678
 
 
3679
  for (target_tbl= (TableList *)lex->auxiliary_table_list.first;
 
3680
       target_tbl; target_tbl= target_tbl->next_local)
 
3681
  {
 
3682
    lex->table_count++;
 
3683
    /* All tables in aux_tables must be found in FROM PART */
 
3684
    TableList *walk= multi_delete_table_match(lex, target_tbl, tables);
 
3685
    if (!walk)
 
3686
      return(true);
 
3687
    if (!walk->derived)
 
3688
    {
 
3689
      target_tbl->table_name= walk->table_name;
 
3690
      target_tbl->table_name_length= walk->table_name_length;
 
3691
    }
 
3692
    walk->updating= target_tbl->updating;
 
3693
    walk->lock_type= target_tbl->lock_type;
 
3694
    target_tbl->correspondent_table= walk;      // Remember corresponding table
 
3695
  }
 
3696
  return(false);
 
3697
}
 
3698
 
 
3699
 
 
3700
/**
 
3701
  simple UPDATE query pre-check.
 
3702
 
 
3703
  @param session                Thread handler
 
3704
  @param tables Global table list
 
3705
 
 
3706
  @retval
 
3707
    false OK
 
3708
  @retval
 
3709
    true  Error
 
3710
*/
 
3711
 
1487
3712
bool update_precheck(Session *session, TableList *)
1488
3713
{
1489
 
  const char *msg= 0;
1490
 
  LEX *lex= session->lex;
1491
 
  Select_Lex *select_lex= &lex->select_lex;
1492
 
 
1493
3714
  if (session->lex->select_lex.item_list.elements != session->lex->value_list.elements)
1494
3715
  {
1495
3716
    my_message(ER_WRONG_VALUE_COUNT, ER(ER_WRONG_VALUE_COUNT), MYF(0));
1496
3717
    return(true);
1497
3718
  }
1498
 
 
1499
 
  if (session->lex->select_lex.table_list.elements > 1)
1500
 
  {
1501
 
    if (select_lex->order_list.elements)
1502
 
      msg= "ORDER BY";
1503
 
    else if (select_lex->select_limit)
1504
 
      msg= "LIMIT";
1505
 
    if (msg)
1506
 
    {
1507
 
      my_error(ER_WRONG_USAGE, MYF(0), "UPDATE", msg);
1508
 
      return(true);
1509
 
    }
1510
 
  }
1511
3719
  return(false);
1512
3720
}
1513
3721
 
1542
3750
 
1543
3751
 
1544
3752
/**
 
3753
  CREATE TABLE query pre-check.
 
3754
 
 
3755
  @param session                        Thread handler
 
3756
  @param tables         Global table list
 
3757
  @param create_table           Table which will be created
 
3758
 
 
3759
  @retval
 
3760
    false   OK
 
3761
  @retval
 
3762
    true   Error
 
3763
*/
 
3764
 
 
3765
bool create_table_precheck(Session *, TableList *,
 
3766
                           TableList *create_table)
 
3767
{
 
3768
  bool error= true;                                 // Error message is given
 
3769
 
 
3770
  if (create_table && (strcmp(create_table->db, "information_schema") == 0))
 
3771
  {
 
3772
    my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), "", "", INFORMATION_SCHEMA_NAME.c_str());
 
3773
    return(true);
 
3774
  }
 
3775
 
 
3776
  error= false;
 
3777
 
 
3778
  return(error);
 
3779
}
 
3780
 
 
3781
 
 
3782
/**
1545
3783
  negate given expression.
1546
3784
 
1547
3785
  @param session  thread handler
1650
3888
}
1651
3889
 
1652
3890
 
 
3891
/*
 
3892
  Check if path does not contain mysql data home directory
 
3893
  SYNOPSIS
 
3894
    test_if_data_home_dir()
 
3895
    dir                     directory
 
3896
    conv_home_dir           converted data home directory
 
3897
    home_dir_len            converted data home directory length
 
3898
 
 
3899
  RETURN VALUES
 
3900
    0   ok
 
3901
    1   error
 
3902
*/
 
3903
 
 
3904
bool test_if_data_home_dir(const char *dir)
 
3905
{
 
3906
  char path[FN_REFLEN], conv_path[FN_REFLEN];
 
3907
  uint32_t dir_len, home_dir_len= strlen(drizzle_unpacked_real_data_home);
 
3908
 
 
3909
  if (!dir)
 
3910
    return(0);
 
3911
 
 
3912
  (void) fn_format(path, dir, "", "",
 
3913
                   (MY_RETURN_REAL_PATH|MY_RESOLVE_SYMLINKS));
 
3914
  dir_len= unpack_dirname(conv_path, dir);
 
3915
 
 
3916
  if (home_dir_len < dir_len)
 
3917
  {
 
3918
    if (!my_strnncoll(character_set_filesystem,
 
3919
                      (const unsigned char*) conv_path, home_dir_len,
 
3920
                      (const unsigned char*) drizzle_unpacked_real_data_home,
 
3921
                      home_dir_len))
 
3922
      return(1);
 
3923
  }
 
3924
  return(0);
 
3925
}
 
3926
 
 
3927
 
 
3928
extern int DRIZZLEparse(void *session); // from sql_yacc.cc
 
3929
 
 
3930
 
1653
3931
/**
1654
3932
  This is a wrapper of DRIZZLEparse(). All the code should call parse_sql()
1655
3933
  instead of DRIZZLEparse().
1662
3940
    @retval true on parsing error.
1663
3941
*/
1664
3942
 
1665
 
static bool parse_sql(Session *session, Lex_input_stream *lip)
 
3943
bool parse_sql(Session *session, Lex_input_stream *lip)
1666
3944
{
1667
3945
  assert(session->m_lip == NULL);
1668
3946
 
1669
 
  DRIZZLE_QUERY_PARSE_START(session->getQueryString()->c_str());
1670
 
 
1671
3947
  /* Set Lex_input_stream. */
1672
3948
 
1673
3949
  session->m_lip= lip;
1684
3960
 
1685
3961
  session->m_lip= NULL;
1686
3962
 
1687
 
  DRIZZLE_QUERY_PARSE_DONE(mysql_parse_status || session->is_fatal_error);
1688
 
 
1689
3963
  /* That's it. */
1690
3964
 
1691
3965
  return mysql_parse_status || session->is_fatal_error;
1694
3968
/**
1695
3969
  @} (end of group Runtime_Environment)
1696
3970
*/
1697
 
 
1698
 
} /* namespace drizzled */