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