~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_parse.cc

  • Committer: Brian Aker
  • Date: 2008-10-18 15:43:20 UTC
  • mto: (492.3.20 drizzle-clean-code)
  • mto: This revision was merged to the branch mainline in revision 530.
  • Revision ID: brian@tangent.org-20081018154320-jc9jyij3mdf08abp
Updating tests.

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