~drizzle-trunk/drizzle/development

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