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