~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_parse.cc

  • Committer: Lee
  • Date: 2009-01-01 17:36:53 UTC
  • mto: (758.1.3 devel)
  • mto: This revision was merged to the branch mainline in revision 759.
  • Revision ID: lbieber@lbieber-desktop-20090101173653-qo5945pnje5j3vuu
more header file cleanup

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