~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_parse.cc

  • Committer: Eric Herman
  • Date: 2008-12-07 15:29:44 UTC
  • mto: (656.1.14 devel)
  • mto: This revision was merged to the branch mainline in revision 670.
  • Revision ID: eric@mysql.com-20081207152944-cq1nx1cyi0huqj0f
Added pointer to online version of the FAQ

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