~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_parse.cc

  • Committer: Monty Taylor
  • Date: 2009-03-20 06:30:59 UTC
  • mfrom: (942.1.17 plugin-registration)
  • mto: This revision was merged to the branch mainline in revision 958.
  • Revision ID: mordred@inaugust.com-20090320063059-lr9hqvw15stxxgn3
Merged plugin registration branch.

Show diffs side-by-side

added added

removed removed

Lines of Context:
11
11
 
12
12
   You should have received a copy of the GNU General Public License
13
13
   along with this program; if not, write to the Free Software
14
 
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
15
 
 
16
 
#include "config.h"
 
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
17
15
 
18
16
#define DRIZZLE_LEX 1
19
 
 
20
 
#include <drizzled/my_hash.h>
 
17
#include <drizzled/server_includes.h>
 
18
#include <libdrizzleclient/libdrizzle.h>
 
19
#include <libdrizzleclient/errmsg.h>
 
20
#include <mysys/hash.h>
 
21
#include <drizzled/logging.h>
 
22
#include <drizzled/db.h>
21
23
#include <drizzled/error.h>
22
24
#include <drizzled/nested_join.h>
23
25
#include <drizzled/query_id.h>
24
 
#include "drizzled/transaction_services.h"
25
26
#include <drizzled/sql_parse.h>
26
27
#include <drizzled/data_home.h>
27
28
#include <drizzled/sql_base.h>
28
29
#include <drizzled/show.h>
29
 
#include <drizzled/db.h>
 
30
#include <drizzled/rename.h>
30
31
#include <drizzled/function/time/unix_timestamp.h>
31
32
#include <drizzled/function/get_system_var.h>
32
33
#include <drizzled/item/cmpfunc.h>
33
34
#include <drizzled/item/null.h>
34
35
#include <drizzled/session.h>
35
36
#include <drizzled/sql_load.h>
 
37
#include <drizzled/connect.h>
36
38
#include <drizzled/lock.h>
37
39
#include <drizzled/select_send.h>
38
 
#include <drizzled/plugin/client.h>
39
 
#include <drizzled/statement.h>
40
 
#include <drizzled/statement/alter_table.h>
41
 
#include "drizzled/probes.h"
42
 
#include "drizzled/session/cache.h"
43
 
#include "drizzled/global_charset_info.h"
44
 
 
45
 
#include "drizzled/plugin/logging.h"
46
 
#include "drizzled/plugin/query_rewrite.h"
47
 
#include "drizzled/plugin/query_cache.h"
48
 
#include "drizzled/plugin/authorization.h"
49
 
#include "drizzled/optimizer/explain_plan.h"
50
 
#include "drizzled/pthread_globals.h"
51
 
#include "drizzled/plugin/event_observer.h"
52
 
 
53
 
#include <limits.h>
54
 
 
55
40
#include <bitset>
56
 
#include <algorithm>
57
 
#include <boost/date_time.hpp>
58
 
#include "drizzled/internal/my_sys.h"
59
41
 
60
42
using namespace std;
61
43
 
62
 
extern int DRIZZLEparse(void *session); // from sql_yacc.cc
63
 
 
64
 
namespace drizzled
65
 
{
66
 
 
67
 
/* Prototypes */
68
 
bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
69
 
static bool parse_sql(Session *session, Lex_input_stream *lip);
70
 
void mysql_parse(Session *session, const char *inBuf, uint32_t length);
71
 
 
72
44
/**
73
45
  @defgroup Runtime_Environment Runtime Environment
74
46
  @{
76
48
 
77
49
extern size_t my_thread_stack_size;
78
50
extern const CHARSET_INFO *character_set_filesystem;
 
51
const char *any_db="*any*";     // Special symbol for check_access
79
52
 
80
53
const LEX_STRING command_name[COM_END+1]={
81
54
  { C_STRING_WITH_LEN("Sleep") },
92
65
  "NON-EXISTING", "ACTIVE", "IDLE", "PREPARED"
93
66
};
94
67
 
 
68
static void unlock_locked_tables(Session *session)
 
69
{
 
70
  if (session->locked_tables)
 
71
  {
 
72
    session->lock=session->locked_tables;
 
73
    session->locked_tables=0;                   // Will be automatically closed
 
74
    close_thread_tables(session);                       // Free tables
 
75
  }
 
76
}
 
77
 
95
78
/**
96
79
  Mark all commands that somehow changes a table.
97
80
 
125
108
  sql_command_flags[SQLCOM_DROP_INDEX]=     CF_CHANGES_DATA;
126
109
 
127
110
  sql_command_flags[SQLCOM_UPDATE]=         CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
 
111
  sql_command_flags[SQLCOM_UPDATE_MULTI]=   CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
128
112
  sql_command_flags[SQLCOM_INSERT]=         CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
129
113
  sql_command_flags[SQLCOM_INSERT_SELECT]=  CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
130
114
  sql_command_flags[SQLCOM_DELETE]=         CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
 
115
  sql_command_flags[SQLCOM_DELETE_MULTI]=   CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
131
116
  sql_command_flags[SQLCOM_REPLACE]=        CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
132
117
  sql_command_flags[SQLCOM_REPLACE_SELECT]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
133
118
 
 
119
  sql_command_flags[SQLCOM_SHOW_STATUS]=      CF_STATUS_COMMAND;
 
120
  sql_command_flags[SQLCOM_SHOW_DATABASES]=   CF_STATUS_COMMAND;
 
121
  sql_command_flags[SQLCOM_SHOW_OPEN_TABLES]= CF_STATUS_COMMAND;
 
122
  sql_command_flags[SQLCOM_SHOW_FIELDS]=      CF_STATUS_COMMAND;
 
123
  sql_command_flags[SQLCOM_SHOW_KEYS]=        CF_STATUS_COMMAND;
 
124
  sql_command_flags[SQLCOM_SHOW_VARIABLES]=   CF_STATUS_COMMAND;
134
125
  sql_command_flags[SQLCOM_SHOW_WARNS]= CF_STATUS_COMMAND;
135
126
  sql_command_flags[SQLCOM_SHOW_ERRORS]= CF_STATUS_COMMAND;
 
127
  sql_command_flags[SQLCOM_SHOW_ENGINE_STATUS]= CF_STATUS_COMMAND;
 
128
  sql_command_flags[SQLCOM_SHOW_PROCESSLIST]= CF_STATUS_COMMAND;
136
129
  sql_command_flags[SQLCOM_SHOW_CREATE_DB]=  CF_STATUS_COMMAND;
137
130
  sql_command_flags[SQLCOM_SHOW_CREATE]=  CF_STATUS_COMMAND;
138
131
 
 
132
   sql_command_flags[SQLCOM_SHOW_TABLES]=       (CF_STATUS_COMMAND |
 
133
                                               CF_SHOW_TABLE_COMMAND);
 
134
  sql_command_flags[SQLCOM_SHOW_TABLE_STATUS]= (CF_STATUS_COMMAND |
 
135
                                                CF_SHOW_TABLE_COMMAND);
139
136
  /*
140
137
    The following admin table operations are allowed
141
138
    on log tables.
142
139
  */
 
140
  sql_command_flags[SQLCOM_REPAIR]=           CF_WRITE_LOGS_COMMAND;
 
141
  sql_command_flags[SQLCOM_OPTIMIZE]=         CF_WRITE_LOGS_COMMAND;
143
142
  sql_command_flags[SQLCOM_ANALYZE]=          CF_WRITE_LOGS_COMMAND;
144
143
}
145
144
 
 
145
 
 
146
bool is_update_query(enum enum_sql_command command)
 
147
{
 
148
  assert(command >= 0 && command <= SQLCOM_END);
 
149
  return (sql_command_flags[command].test(CF_BIT_CHANGES_DATA));
 
150
}
 
151
 
 
152
void execute_init_command(Session *session, sys_var_str *init_command_var,
 
153
                          pthread_rwlock_t *var_mutex)
 
154
{
 
155
  Vio* save_vio;
 
156
  ulong save_client_capabilities;
 
157
 
 
158
  session->set_proc_info("Execution of init_command");
 
159
  /*
 
160
    We need to lock init_command_var because
 
161
    during execution of init_command_var query
 
162
    values of init_command_var can't be changed
 
163
  */
 
164
  pthread_rwlock_rdlock(var_mutex);
 
165
  save_client_capabilities= session->client_capabilities;
 
166
  session->client_capabilities|= CLIENT_MULTI_STATEMENTS;
 
167
  /*
 
168
    We don't need return result of execution to client side.
 
169
    To forbid this we should set session->net.vio to 0.
 
170
  */
 
171
  save_vio= session->net.vio;
 
172
  session->net.vio= 0;
 
173
  dispatch_command(COM_QUERY, session,
 
174
                   init_command_var->value,
 
175
                   init_command_var->value_length);
 
176
  pthread_rwlock_unlock(var_mutex);
 
177
  session->client_capabilities= save_client_capabilities;
 
178
  session->net.vio= save_vio;
 
179
}
 
180
 
146
181
/**
147
182
  Perform one connection-level (COM_XXXX) command.
148
183
 
167
202
bool dispatch_command(enum enum_server_command command, Session *session,
168
203
                      char* packet, uint32_t packet_length)
169
204
{
 
205
  NET *net= &session->net;
170
206
  bool error= 0;
 
207
  int error_code;
171
208
  Query_id &query_id= Query_id::get_query_id();
172
209
 
173
 
  DRIZZLE_COMMAND_START(session->thread_id, command);
174
 
 
175
 
  session->command= command;
 
210
  session->command=command;
176
211
  session->lex->sql_command= SQLCOM_END; /* to avoid confusing VIEW detectors */
177
212
  session->set_time();
178
 
  session->setQueryId(query_id.value());
 
213
  if ((error_code= pthread_mutex_lock(&LOCK_thread_count)))
 
214
    assert(error_code == 0); /* Always will assert */
 
215
 
 
216
  session->query_id= query_id.value();
179
217
 
180
218
  switch( command ) {
181
219
  /* Ignore these statements. */
183
221
    break;
184
222
  /* Increase id and count all other statements. */
185
223
  default:
186
 
    session->status_var.questions++;
 
224
    statistic_increment(session->status_var.questions, &LOCK_status);
187
225
    query_id.next();
188
226
  }
189
227
 
 
228
  thread_running++;
190
229
  /* TODO: set session->lex->sql_command to SQLCOM_END here */
 
230
  pthread_mutex_unlock(&LOCK_thread_count);
191
231
 
192
 
  plugin::Logging::preDo(session);
193
 
  if (unlikely(plugin::EventObserver::beforeStatement(*session)))
194
 
  {
195
 
    // We should do something about an error...
196
 
  }
 
232
  logging_pre_do(session);
197
233
 
198
234
  session->server_status&=
199
235
           ~(SERVER_QUERY_NO_INDEX_USED | SERVER_QUERY_NO_GOOD_INDEX_USED);
200
236
  switch (command) {
201
237
  case COM_INIT_DB:
202
238
  {
203
 
    if (packet_length == 0)
204
 
    {
205
 
      my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
206
 
      break;
207
 
    }
208
 
 
209
 
    string tmp(packet, packet_length);
210
 
 
211
 
    SchemaIdentifier identifier(tmp);
212
 
 
213
 
    if (not mysql_change_db(session, identifier))
 
239
    LEX_STRING tmp;
 
240
    status_var_increment(session->status_var.com_stat[SQLCOM_CHANGE_DB]);
 
241
    session->convert_string(&tmp, system_charset_info,
 
242
                        packet, packet_length, session->charset());
 
243
    if (!mysql_change_db(session, &tmp, false))
214
244
    {
215
245
      session->my_ok();
216
246
    }
218
248
  }
219
249
  case COM_QUERY:
220
250
  {
221
 
    if (not session->readAndStoreQuery(packet, packet_length))
 
251
    if (! session->readAndStoreQuery(packet, packet_length))
222
252
      break;                                    // fatal error is set
223
 
    DRIZZLE_QUERY_START(session->getQueryString()->c_str(),
224
 
                        session->thread_id,
225
 
                        const_cast<const char *>(session->schema()->c_str()));
226
 
 
227
 
    mysql_parse(session, session->getQueryString()->c_str(), session->getQueryString()->length());
228
 
 
 
253
    char *packet_end= session->query + session->query_length;
 
254
    const char* end_of_stmt= NULL;
 
255
 
 
256
    mysql_parse(session, session->query, session->query_length, &end_of_stmt);
 
257
 
 
258
    while (!session->killed && (end_of_stmt != NULL) && ! session->is_error())
 
259
    {
 
260
      char *beginning_of_next_stmt= (char*) end_of_stmt;
 
261
 
 
262
      drizzleclient_net_end_statement(session);
 
263
      /*
 
264
        Multiple queries exits, execute them individually
 
265
      */
 
266
      close_thread_tables(session);
 
267
      ulong length= (ulong)(packet_end - beginning_of_next_stmt);
 
268
 
 
269
      log_slow_statement(session);
 
270
 
 
271
      /* Remove garbage at start of query */
 
272
      while (length > 0 && my_isspace(session->charset(), *beginning_of_next_stmt))
 
273
      {
 
274
        beginning_of_next_stmt++;
 
275
        length--;
 
276
      }
 
277
 
 
278
      /*
 
279
        Count each statement from the client.
 
280
      */
 
281
      statistic_increment(session->status_var.questions, &LOCK_status);
 
282
      session->query_id= query_id.next();
 
283
      session->set_time(); /* Reset the query start time. */
 
284
      pthread_mutex_lock(&LOCK_thread_count);
 
285
      session->query_length= length;
 
286
      session->query= beginning_of_next_stmt;
 
287
      pthread_mutex_unlock(&LOCK_thread_count);
 
288
      /* TODO: set session->lex->sql_command to SQLCOM_END here */
 
289
 
 
290
      mysql_parse(session, beginning_of_next_stmt, length, &end_of_stmt);
 
291
    }
229
292
    break;
230
293
  }
231
294
  case COM_QUIT:
232
295
    /* We don't calculate statistics for this command */
 
296
    net->error=0;                               // Don't give 'abort' message
233
297
    session->main_da.disable_status();              // Don't send anything back
234
298
    error=true;                                 // End server
235
299
    break;
236
300
  case COM_SHUTDOWN:
237
301
  {
238
 
    session->status_var.com_other++;
 
302
    status_var_increment(session->status_var.com_other);
239
303
    session->my_eof();
240
 
    session->close_thread_tables();                     // Free before kill
 
304
    close_thread_tables(session);                       // Free before kill
241
305
    kill_drizzle();
242
306
    error=true;
243
307
    break;
244
308
  }
245
309
  case COM_PING:
246
 
    session->status_var.com_other++;
 
310
    status_var_increment(session->status_var.com_other);
247
311
    session->my_ok();                           // Tell client we are alive
248
312
    break;
249
313
  case COM_SLEEP:
256
320
 
257
321
  /* If commit fails, we should be able to reset the OK status. */
258
322
  session->main_da.can_overwrite_status= true;
259
 
  TransactionServices &transaction_services= TransactionServices::singleton();
260
 
  transaction_services.autocommitOrRollback(session, session->is_error());
 
323
  ha_autocommit_or_rollback(session, session->is_error());
261
324
  session->main_da.can_overwrite_status= false;
262
325
 
263
326
  session->transaction.stmt.reset();
269
332
    if (! session->main_da.is_set())
270
333
      session->send_kill_message();
271
334
  }
272
 
  if (session->getKilled() == Session::KILL_QUERY || session->getKilled() == Session::KILL_BAD_DATA)
273
 
  {
274
 
    session->setKilled(Session::NOT_KILLED);
275
 
    session->setAbort(false);
276
 
  }
277
 
 
278
 
  /* Can not be true, but do not take chances in production. */
279
 
  assert(! session->main_da.is_sent);
280
 
 
281
 
  switch (session->main_da.status())
282
 
  {
283
 
  case Diagnostics_area::DA_ERROR:
284
 
    /* The query failed, send error to log and abort bootstrap. */
285
 
    session->client->sendError(session->main_da.sql_errno(),
286
 
                               session->main_da.message());
287
 
    break;
288
 
 
289
 
  case Diagnostics_area::DA_EOF:
290
 
    session->client->sendEOF();
291
 
    break;
292
 
 
293
 
  case Diagnostics_area::DA_OK:
294
 
    session->client->sendOK();
295
 
    break;
296
 
 
297
 
  case Diagnostics_area::DA_DISABLED:
298
 
    break;
299
 
 
300
 
  case Diagnostics_area::DA_EMPTY:
301
 
  default:
302
 
    session->client->sendOK();
303
 
    break;
304
 
  }
305
 
 
306
 
  session->main_da.is_sent= true;
 
335
  if (session->killed == Session::KILL_QUERY || session->killed == Session::KILL_BAD_DATA)
 
336
  {
 
337
    session->killed= Session::NOT_KILLED;
 
338
    session->mysys_var->abort= 0;
 
339
  }
 
340
 
 
341
  drizzleclient_net_end_statement(session);
307
342
 
308
343
  session->set_proc_info("closing tables");
309
344
  /* Free tables */
310
 
  session->close_thread_tables();
311
 
 
312
 
  plugin::Logging::postDo(session);
313
 
  if (unlikely(plugin::EventObserver::afterStatement(*session)))
314
 
  {
315
 
    // We should do something about an error...
316
 
  }
317
 
 
318
 
  /* Store temp state for processlist */
 
345
  close_thread_tables(session);
 
346
 
 
347
  log_slow_statement(session);
 
348
 
319
349
  session->set_proc_info("cleaning up");
320
 
  session->command= COM_SLEEP;
321
 
  session->resetQueryString();
322
 
 
323
 
  session->set_proc_info(NULL);
324
 
  session->mem_root->free_root(MYF(memory::KEEP_PREALLOC));
325
 
 
326
 
  if (DRIZZLE_QUERY_DONE_ENABLED() || DRIZZLE_COMMAND_DONE_ENABLED())
327
 
  {
328
 
    if (command == COM_QUERY)
329
 
    {
330
 
      DRIZZLE_QUERY_DONE(session->is_error());
331
 
    }
332
 
    DRIZZLE_COMMAND_DONE(session->is_error());
333
 
  }
334
 
 
335
 
  return error;
 
350
  pthread_mutex_lock(&LOCK_thread_count); // For process list
 
351
  session->set_proc_info(0);
 
352
  session->command=COM_SLEEP;
 
353
  session->query=0;
 
354
  session->query_length=0;
 
355
  thread_running--;
 
356
  pthread_mutex_unlock(&LOCK_thread_count);
 
357
  session->packet.shrink(session->variables.net_buffer_length); // Reclaim some memory
 
358
  free_root(session->mem_root,MYF(MY_KEEP_PREALLOC));
 
359
  return(error);
 
360
}
 
361
 
 
362
 
 
363
void log_slow_statement(Session *session)
 
364
{
 
365
  logging_post_do(session);
 
366
 
 
367
  return;
336
368
}
337
369
 
338
370
 
344
376
    It prepares a Select_Lex and a TableList object to represent the
345
377
    given command as a SELECT parse tree.
346
378
 
347
 
  @param session           thread handle
348
 
  @param lex               current lex
349
 
  @param table_ident       table alias if it's used
350
 
  @param schema_table_name the name of the INFORMATION_SCHEMA table to be
351
 
                           created
 
379
  @param session              thread handle
 
380
  @param lex              current lex
 
381
  @param table_ident      table alias if it's used
 
382
  @param schema_table_idx the type of the INFORMATION_SCHEMA table to be
 
383
                          created
352
384
 
353
385
  @note
354
386
    Due to the way this function works with memory and LEX it cannot
361
393
    1                 out of memory or SHOW commands are not allowed
362
394
                      in this version of the server.
363
395
*/
364
 
static bool _schema_select(Session *session, Select_Lex *sel,
365
 
                           const string& schema_table_name)
366
 
{
367
 
  LEX_STRING db, table;
368
 
  bitset<NUM_OF_TABLE_OPTIONS> table_options;
369
 
  /*
370
 
     We have to make non const db_name & table_name
371
 
     because of lower_case_table_names
372
 
  */
373
 
  session->make_lex_string(&db, "data_dictionary", sizeof("data_dictionary"), false);
374
 
  session->make_lex_string(&table, schema_table_name, false);
375
 
 
376
 
  if (! sel->add_table_to_list(session, new Table_ident(db, table),
377
 
                               NULL, table_options, TL_READ))
378
 
  {
379
 
    return true;
380
 
  }
381
 
  return false;
382
 
}
383
 
 
384
 
int prepare_new_schema_table(Session *session, LEX *lex,
385
 
                             const string& schema_table_name)
 
396
 
 
397
int prepare_schema_table(Session *session, LEX *lex, Table_ident *table_ident,
 
398
                         enum enum_schema_tables schema_table_idx)
386
399
{
387
400
  Select_Lex *schema_select_lex= NULL;
388
401
 
 
402
  switch (schema_table_idx) {
 
403
  case SCH_SCHEMATA:
 
404
    break;
 
405
  case SCH_TABLE_NAMES:
 
406
  case SCH_TABLES:
 
407
    {
 
408
      LEX_STRING db;
 
409
      size_t dummy;
 
410
      if (lex->select_lex.db == NULL &&
 
411
          lex->copy_db_to(&lex->select_lex.db, &dummy))
 
412
      {
 
413
        return(1);
 
414
      }
 
415
      schema_select_lex= new Select_Lex();
 
416
      db.str= schema_select_lex->db= lex->select_lex.db;
 
417
      schema_select_lex->table_list.first= NULL;
 
418
      db.length= strlen(db.str);
 
419
 
 
420
      if (check_db_name(&db))
 
421
      {
 
422
        my_error(ER_WRONG_DB_NAME, MYF(0), db.str);
 
423
        return(1);
 
424
      }
 
425
      break;
 
426
    }
 
427
  case SCH_COLUMNS:
 
428
  case SCH_STATISTICS:
 
429
  {
 
430
    assert(table_ident);
 
431
    TableList **query_tables_last= lex->query_tables_last;
 
432
    schema_select_lex= new Select_Lex();
 
433
    /* 'parent_lex' is used in init_query() so it must be before it. */
 
434
    schema_select_lex->parent_lex= lex;
 
435
    schema_select_lex->init_query();
 
436
    if (!schema_select_lex->add_table_to_list(session, table_ident, 0, 0, TL_READ))
 
437
      return(1);
 
438
    lex->query_tables_last= query_tables_last;
 
439
    break;
 
440
  }
 
441
  case SCH_OPEN_TABLES:
 
442
  case SCH_VARIABLES:
 
443
  case SCH_STATUS:
 
444
  case SCH_CHARSETS:
 
445
  case SCH_COLLATIONS:
 
446
  case SCH_COLLATION_CHARACTER_SET_APPLICABILITY:
 
447
  case SCH_TABLE_CONSTRAINTS:
 
448
  case SCH_KEY_COLUMN_USAGE:
 
449
  default:
 
450
    break;
 
451
  }
 
452
 
389
453
  Select_Lex *select_lex= lex->current_select;
390
454
  assert(select_lex);
391
 
  if (_schema_select(session, select_lex, schema_table_name))
 
455
  if (make_schema_select(session, select_lex, schema_table_idx))
392
456
  {
393
457
    return(1);
394
458
  }
395
459
  TableList *table_list= (TableList*) select_lex->table_list.first;
396
460
  assert(table_list);
397
461
  table_list->schema_select_lex= schema_select_lex;
398
 
 
399
 
  return 0;
 
462
  table_list->schema_table_reformed= 1;
 
463
  return(0);
400
464
}
401
465
 
402
466
/**
429
493
    true        Error
430
494
*/
431
495
 
432
 
static int mysql_execute_command(Session *session)
 
496
int
 
497
mysql_execute_command(Session *session)
433
498
{
434
 
  bool res= false;
 
499
  int res= false;
 
500
  bool need_start_waiting= false; // have protection against global read lock
435
501
  LEX  *lex= session->lex;
436
502
  /* first Select_Lex (have special meaning for many of non-SELECTcommands) */
437
503
  Select_Lex *select_lex= &lex->select_lex;
 
504
  /* first table of first Select_Lex */
 
505
  TableList *first_table= (TableList*) select_lex->table_list.first;
438
506
  /* list of all tables in query */
439
507
  TableList *all_tables;
 
508
  /* most outer Select_Lex_Unit of query */
 
509
  Select_Lex_Unit *unit= &lex->unit;
 
510
  /* Saved variable value */
440
511
 
441
512
  /*
442
513
    In many cases first table of main Select_Lex have special meaning =>
468
539
    variables, but for now this is probably good enough.
469
540
    Don't reset warnings when executing a stored routine.
470
541
  */
471
 
  if (all_tables || ! lex->is_single_level_stmt())
472
 
  {
 
542
  if (all_tables || !lex->is_single_level_stmt())
473
543
    drizzle_reset_errors(session, 0);
474
 
  }
475
 
 
476
 
  assert(session->transaction.stmt.hasModifiedNonTransData() == false);
477
 
 
478
 
  /* now we are ready to execute the statement */
479
 
  res= lex->statement->execute();
 
544
 
 
545
  status_var_increment(session->status_var.com_stat[lex->sql_command]);
 
546
 
 
547
  assert(session->transaction.stmt.modified_non_trans_table == false);
 
548
 
 
549
  switch (lex->sql_command) {
 
550
  case SQLCOM_SHOW_STATUS:
 
551
  {
 
552
    system_status_var old_status_var= session->status_var;
 
553
    session->initial_status_var= &old_status_var;
 
554
    res= execute_sqlcom_select(session, all_tables);
 
555
    /* Don't log SHOW STATUS commands to slow query log */
 
556
    session->server_status&= ~(SERVER_QUERY_NO_INDEX_USED |
 
557
                           SERVER_QUERY_NO_GOOD_INDEX_USED);
 
558
    /*
 
559
      restore status variables, as we don't want 'show status' to cause
 
560
      changes
 
561
    */
 
562
    pthread_mutex_lock(&LOCK_status);
 
563
    add_diff_to_status(&global_status_var, &session->status_var,
 
564
                       &old_status_var);
 
565
    session->status_var= old_status_var;
 
566
    pthread_mutex_unlock(&LOCK_status);
 
567
    break;
 
568
  }
 
569
  case SQLCOM_SHOW_DATABASES:
 
570
  case SQLCOM_SHOW_TABLES:
 
571
  case SQLCOM_SHOW_TABLE_STATUS:
 
572
  case SQLCOM_SHOW_OPEN_TABLES:
 
573
  case SQLCOM_SHOW_FIELDS:
 
574
  case SQLCOM_SHOW_KEYS:
 
575
  case SQLCOM_SHOW_VARIABLES:
 
576
  case SQLCOM_SELECT:
 
577
  {
 
578
    session->status_var.last_query_cost= 0.0;
 
579
    res= execute_sqlcom_select(session, all_tables);
 
580
    break;
 
581
  }
 
582
  case SQLCOM_EMPTY_QUERY:
 
583
    session->my_ok();
 
584
    break;
 
585
 
 
586
  case SQLCOM_SHOW_WARNS:
 
587
  {
 
588
    res= mysqld_show_warnings(session, (uint32_t)
 
589
                              ((1L << (uint32_t) DRIZZLE_ERROR::WARN_LEVEL_NOTE) |
 
590
                               (1L << (uint32_t) DRIZZLE_ERROR::WARN_LEVEL_WARN) |
 
591
                               (1L << (uint32_t) DRIZZLE_ERROR::WARN_LEVEL_ERROR)
 
592
                               ));
 
593
    break;
 
594
  }
 
595
  case SQLCOM_SHOW_ERRORS:
 
596
  {
 
597
    res= mysqld_show_warnings(session, (uint32_t)
 
598
                              (1L << (uint32_t) DRIZZLE_ERROR::WARN_LEVEL_ERROR));
 
599
    break;
 
600
  }
 
601
  case SQLCOM_ASSIGN_TO_KEYCACHE:
 
602
  {
 
603
    assert(first_table == all_tables && first_table != 0);
 
604
    res= mysql_assign_to_keycache(session, first_table, &lex->ident);
 
605
    break;
 
606
  }
 
607
  case SQLCOM_SHOW_ENGINE_STATUS:
 
608
    {
 
609
      res = ha_show_status(session, lex->create_info.db_type, HA_ENGINE_STATUS);
 
610
      break;
 
611
    }
 
612
  case SQLCOM_CREATE_TABLE:
 
613
  {
 
614
    /* If CREATE TABLE of non-temporary table, do implicit commit */
 
615
    if (!(lex->create_info.options & HA_LEX_CREATE_TMP_TABLE))
 
616
    {
 
617
      if (! session->endActiveTransaction())
 
618
      {
 
619
        res= -1;
 
620
        break;
 
621
      }
 
622
    }
 
623
    assert(first_table == all_tables && first_table != 0);
 
624
    bool link_to_local;
 
625
    // Skip first table, which is the table we are creating
 
626
    TableList *create_table= lex->unlink_first_table(&link_to_local);
 
627
    TableList *select_tables= lex->query_tables;
 
628
    /*
 
629
      Code below (especially in mysql_create_table() and select_create
 
630
      methods) may modify HA_CREATE_INFO structure in LEX, so we have to
 
631
      use a copy of this structure to make execution prepared statement-
 
632
      safe. A shallow copy is enough as this code won't modify any memory
 
633
      referenced from this structure.
 
634
    */
 
635
    HA_CREATE_INFO create_info(lex->create_info);
 
636
    /*
 
637
      We need to copy alter_info for the same reasons of re-execution
 
638
      safety, only in case of Alter_info we have to do (almost) a deep
 
639
      copy.
 
640
    */
 
641
    Alter_info alter_info(lex->alter_info, session->mem_root);
 
642
 
 
643
    if (session->is_fatal_error)
 
644
    {
 
645
      /* If out of memory when creating a copy of alter_info. */
 
646
      res= 1;
 
647
      goto end_with_restore_list;
 
648
    }
 
649
 
 
650
    if ((res= create_table_precheck(session, select_tables, create_table)))
 
651
      goto end_with_restore_list;
 
652
 
 
653
    /* Might have been updated in create_table_precheck */
 
654
    create_info.alias= create_table->alias;
 
655
 
 
656
#ifdef HAVE_READLINK
 
657
    /* Fix names if symlinked tables */
 
658
    if (append_file_to_dir(session, &create_info.data_file_name,
 
659
                           create_table->table_name) ||
 
660
        append_file_to_dir(session, &create_info.index_file_name,
 
661
                           create_table->table_name))
 
662
      goto end_with_restore_list;
 
663
#endif
 
664
    /*
 
665
      The create-select command will open and read-lock the select table
 
666
      and then create, open and write-lock the new table. If a global
 
667
      read lock steps in, we get a deadlock. The write lock waits for
 
668
      the global read lock, while the global read lock waits for the
 
669
      select table to be closed. So we wait until the global readlock is
 
670
      gone before starting both steps. Note that
 
671
      wait_if_global_read_lock() sets a protection against a new global
 
672
      read lock when it succeeds. This needs to be released by
 
673
      start_waiting_global_read_lock(). We protect the normal CREATE
 
674
      TABLE in the same way. That way we avoid that a new table is
 
675
      created during a gobal read lock.
 
676
    */
 
677
    if (!session->locked_tables &&
 
678
        !(need_start_waiting= !wait_if_global_read_lock(session, 0, 1)))
 
679
    {
 
680
      res= 1;
 
681
      goto end_with_restore_list;
 
682
    }
 
683
    if (select_lex->item_list.elements)         // With select
 
684
    {
 
685
      select_result *result;
 
686
 
 
687
      select_lex->options|= SELECT_NO_UNLOCK;
 
688
      unit->set_limit(select_lex);
 
689
 
 
690
      if (!(create_info.options & HA_LEX_CREATE_TMP_TABLE))
 
691
      {
 
692
        lex->link_first_table_back(create_table, link_to_local);
 
693
        create_table->create= true;
 
694
      }
 
695
 
 
696
      if (!(res= open_and_lock_tables(session, lex->query_tables)))
 
697
      {
 
698
        /*
 
699
          Is table which we are changing used somewhere in other parts
 
700
          of query
 
701
        */
 
702
        if (!(create_info.options & HA_LEX_CREATE_TMP_TABLE))
 
703
        {
 
704
          TableList *duplicate;
 
705
          create_table= lex->unlink_first_table(&link_to_local);
 
706
          if ((duplicate= unique_table(session, create_table, select_tables, 0)))
 
707
          {
 
708
            update_non_unique_table_error(create_table, "CREATE", duplicate);
 
709
            res= 1;
 
710
            goto end_with_restore_list;
 
711
          }
 
712
        }
 
713
 
 
714
        /*
 
715
          select_create is currently not re-execution friendly and
 
716
          needs to be created for every execution of a PS/SP.
 
717
        */
 
718
        if ((result= new select_create(create_table,
 
719
                                       &create_info,
 
720
                                       &alter_info,
 
721
                                       select_lex->item_list,
 
722
                                       lex->duplicates,
 
723
                                       lex->ignore,
 
724
                                       select_tables)))
 
725
        {
 
726
          /*
 
727
            CREATE from SELECT give its Select_Lex for SELECT,
 
728
            and item_list belong to SELECT
 
729
          */
 
730
          res= handle_select(session, lex, result, 0);
 
731
          delete result;
 
732
        }
 
733
      }
 
734
      else if (!(create_info.options & HA_LEX_CREATE_TMP_TABLE))
 
735
        create_table= lex->unlink_first_table(&link_to_local);
 
736
 
 
737
    }
 
738
    else
 
739
    {
 
740
      /* So that CREATE TEMPORARY TABLE gets to binlog at commit/rollback */
 
741
      if (create_info.options & HA_LEX_CREATE_TMP_TABLE)
 
742
        session->options|= OPTION_KEEP_LOG;
 
743
      /* regular create */
 
744
      if (create_info.options & HA_LEX_CREATE_TABLE_LIKE)
 
745
        res= mysql_create_like_table(session, create_table, select_tables,
 
746
                                     &create_info);
 
747
      else
 
748
      {
 
749
        res= mysql_create_table(session, create_table->db,
 
750
                                create_table->table_name, &create_info,
 
751
                                &alter_info, 0, 0);
 
752
      }
 
753
      if (!res)
 
754
        session->my_ok();
 
755
    }
 
756
 
 
757
    /* put tables back for PS rexecuting */
 
758
end_with_restore_list:
 
759
    lex->link_first_table_back(create_table, link_to_local);
 
760
    break;
 
761
  }
 
762
  case SQLCOM_CREATE_INDEX:
 
763
    /* Fall through */
 
764
  case SQLCOM_DROP_INDEX:
 
765
  /*
 
766
    CREATE INDEX and DROP INDEX are implemented by calling ALTER
 
767
    TABLE with proper arguments.
 
768
 
 
769
    In the future ALTER TABLE will notice that the request is to
 
770
    only add indexes and create these one by one for the existing
 
771
    table without having to do a full rebuild.
 
772
  */
 
773
  {
 
774
    /* Prepare stack copies to be re-execution safe */
 
775
    HA_CREATE_INFO create_info;
 
776
    Alter_info alter_info(lex->alter_info, session->mem_root);
 
777
 
 
778
    if (session->is_fatal_error) /* out of memory creating a copy of alter_info */
 
779
      goto error;
 
780
 
 
781
    assert(first_table == all_tables && first_table != 0);
 
782
    if (! session->endActiveTransaction())
 
783
      goto error;
 
784
 
 
785
    memset(&create_info, 0, sizeof(create_info));
 
786
    create_info.db_type= 0;
 
787
    create_info.row_type= ROW_TYPE_NOT_USED;
 
788
    create_info.default_table_charset= session->variables.collation_database;
 
789
 
 
790
    res= mysql_alter_table(session, first_table->db, first_table->table_name,
 
791
                           &create_info, first_table, &alter_info,
 
792
                           0, (order_st*) 0, 0);
 
793
    break;
 
794
  }
 
795
  case SQLCOM_ALTER_TABLE:
 
796
    assert(first_table == all_tables && first_table != 0);
 
797
    {
 
798
      /*
 
799
        Code in mysql_alter_table() may modify its HA_CREATE_INFO argument,
 
800
        so we have to use a copy of this structure to make execution
 
801
        prepared statement- safe. A shallow copy is enough as no memory
 
802
        referenced from this structure will be modified.
 
803
      */
 
804
      HA_CREATE_INFO create_info(lex->create_info);
 
805
      Alter_info alter_info(lex->alter_info, session->mem_root);
 
806
 
 
807
      if (session->is_fatal_error) /* out of memory creating a copy of alter_info */
 
808
      {
 
809
        goto error;
 
810
      }
 
811
 
 
812
      /* Must be set in the parser */
 
813
      assert(select_lex->db);
 
814
 
 
815
      { // Rename of table
 
816
          TableList tmp_table;
 
817
          memset(&tmp_table, 0, sizeof(tmp_table));
 
818
          tmp_table.table_name= lex->name.str;
 
819
          tmp_table.db=select_lex->db;
 
820
      }
 
821
 
 
822
      /* Don't yet allow changing of symlinks with ALTER TABLE */
 
823
      if (create_info.data_file_name)
 
824
        push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN, 0,
 
825
                     "DATA DIRECTORY option ignored");
 
826
      if (create_info.index_file_name)
 
827
        push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN, 0,
 
828
                     "INDEX DIRECTORY option ignored");
 
829
      create_info.data_file_name= create_info.index_file_name= NULL;
 
830
      /* ALTER TABLE ends previous transaction */
 
831
      if (! session->endActiveTransaction())
 
832
        goto error;
 
833
 
 
834
      if (!session->locked_tables &&
 
835
          !(need_start_waiting= !wait_if_global_read_lock(session, 0, 1)))
 
836
      {
 
837
        res= 1;
 
838
        break;
 
839
      }
 
840
 
 
841
      res= mysql_alter_table(session, select_lex->db, lex->name.str,
 
842
                             &create_info,
 
843
                             first_table,
 
844
                             &alter_info,
 
845
                             select_lex->order_list.elements,
 
846
                             (order_st *) select_lex->order_list.first,
 
847
                             lex->ignore);
 
848
      break;
 
849
    }
 
850
  case SQLCOM_RENAME_TABLE:
 
851
  {
 
852
    assert(first_table == all_tables && first_table != 0);
 
853
    TableList *table;
 
854
    for (table= first_table; table; table= table->next_local->next_local)
 
855
    {
 
856
      TableList old_list, new_list;
 
857
      /*
 
858
        we do not need initialize old_list and new_list because we will
 
859
        come table[0] and table->next[0] there
 
860
      */
 
861
      old_list= table[0];
 
862
      new_list= table->next_local[0];
 
863
    }
 
864
 
 
865
    if (! session->endActiveTransaction() || drizzle_rename_tables(session, first_table, 0))
 
866
    {
 
867
      goto error;
 
868
    }
 
869
    break;
 
870
  }
 
871
  case SQLCOM_SHOW_CREATE:
 
872
    assert(first_table == all_tables && first_table != 0);
 
873
    {
 
874
      res= drizzled_show_create(session, first_table);
 
875
      break;
 
876
    }
 
877
  case SQLCOM_CHECKSUM:
 
878
  {
 
879
    assert(first_table == all_tables && first_table != 0);
 
880
    res = mysql_checksum_table(session, first_table, &lex->check_opt);
 
881
    break;
 
882
  }
 
883
  case SQLCOM_REPAIR:
 
884
  {
 
885
    assert(first_table == all_tables && first_table != 0);
 
886
    res= mysql_repair_table(session, first_table, &lex->check_opt);
 
887
    /* ! we write after unlocking the table */
 
888
    /*
 
889
      Presumably, REPAIR and binlog writing doesn't require synchronization
 
890
    */
 
891
    write_bin_log(session, true, session->query, session->query_length);
 
892
    select_lex->table_list.first= (unsigned char*) first_table;
 
893
    lex->query_tables=all_tables;
 
894
    break;
 
895
  }
 
896
  case SQLCOM_CHECK:
 
897
  {
 
898
    assert(first_table == all_tables && first_table != 0);
 
899
    res = mysql_check_table(session, first_table, &lex->check_opt);
 
900
    select_lex->table_list.first= (unsigned char*) first_table;
 
901
    lex->query_tables=all_tables;
 
902
    break;
 
903
  }
 
904
  case SQLCOM_ANALYZE:
 
905
  {
 
906
    assert(first_table == all_tables && first_table != 0);
 
907
    res= mysql_analyze_table(session, first_table, &lex->check_opt);
 
908
    /* ! we write after unlocking the table */
 
909
    write_bin_log(session, true, session->query, session->query_length);
 
910
    select_lex->table_list.first= (unsigned char*) first_table;
 
911
    lex->query_tables=all_tables;
 
912
    break;
 
913
  }
 
914
 
 
915
  case SQLCOM_OPTIMIZE:
 
916
  {
 
917
    assert(first_table == all_tables && first_table != 0);
 
918
    res= mysql_optimize_table(session, first_table, &lex->check_opt);
 
919
    /* ! we write after unlocking the table */
 
920
    write_bin_log(session, true, session->query, session->query_length);
 
921
    select_lex->table_list.first= (unsigned char*) first_table;
 
922
    lex->query_tables=all_tables;
 
923
    break;
 
924
  }
 
925
  case SQLCOM_UPDATE:
 
926
    assert(first_table == all_tables && first_table != 0);
 
927
    if ((res= update_precheck(session, all_tables)))
 
928
      break;
 
929
    assert(select_lex->offset_limit == 0);
 
930
    unit->set_limit(select_lex);
 
931
    res= mysql_update(session, all_tables,
 
932
                      select_lex->item_list,
 
933
                      lex->value_list,
 
934
                      select_lex->where,
 
935
                      select_lex->order_list.elements,
 
936
                      (order_st *) select_lex->order_list.first,
 
937
                      unit->select_limit_cnt,
 
938
                      lex->duplicates, lex->ignore);
 
939
    break;
 
940
  case SQLCOM_UPDATE_MULTI:
 
941
  {
 
942
    assert(first_table == all_tables && first_table != 0);
 
943
    if ((res= update_precheck(session, all_tables)))
 
944
      break;
 
945
 
 
946
    if ((res= mysql_multi_update_prepare(session)))
 
947
      break;
 
948
 
 
949
    res= mysql_multi_update(session, all_tables,
 
950
                            &select_lex->item_list,
 
951
                            &lex->value_list,
 
952
                            select_lex->where,
 
953
                            select_lex->options,
 
954
                            lex->duplicates, lex->ignore, unit, select_lex);
 
955
    break;
 
956
  }
 
957
  case SQLCOM_REPLACE:
 
958
  case SQLCOM_INSERT:
 
959
  {
 
960
    assert(first_table == all_tables && first_table != 0);
 
961
    if ((res= insert_precheck(session, all_tables)))
 
962
      break;
 
963
 
 
964
    if (!session->locked_tables &&
 
965
        !(need_start_waiting= !wait_if_global_read_lock(session, 0, 1)))
 
966
    {
 
967
      res= 1;
 
968
      break;
 
969
    }
 
970
 
 
971
    res= mysql_insert(session, all_tables, lex->field_list, lex->many_values,
 
972
                      lex->update_list, lex->value_list,
 
973
                      lex->duplicates, lex->ignore);
 
974
 
 
975
    break;
 
976
  }
 
977
  case SQLCOM_REPLACE_SELECT:
 
978
  case SQLCOM_INSERT_SELECT:
 
979
  {
 
980
    select_result *sel_result;
 
981
    assert(first_table == all_tables && first_table != 0);
 
982
    if ((res= insert_precheck(session, all_tables)))
 
983
      break;
 
984
 
 
985
    /* Fix lock for first table */
 
986
    if (first_table->lock_type == TL_WRITE_DELAYED)
 
987
      first_table->lock_type= TL_WRITE;
 
988
 
 
989
    /* Don't unlock tables until command is written to binary log */
 
990
    select_lex->options|= SELECT_NO_UNLOCK;
 
991
 
 
992
    unit->set_limit(select_lex);
 
993
 
 
994
    if (! session->locked_tables &&
 
995
        ! (need_start_waiting= ! wait_if_global_read_lock(session, 0, 1)))
 
996
    {
 
997
      res= 1;
 
998
      break;
 
999
    }
 
1000
 
 
1001
    if (!(res= open_and_lock_tables(session, all_tables)))
 
1002
    {
 
1003
      /* Skip first table, which is the table we are inserting in */
 
1004
      TableList *second_table= first_table->next_local;
 
1005
      select_lex->table_list.first= (unsigned char*) second_table;
 
1006
      select_lex->context.table_list=
 
1007
        select_lex->context.first_name_resolution_table= second_table;
 
1008
      res= mysql_insert_select_prepare(session);
 
1009
      if (!res && (sel_result= new select_insert(first_table,
 
1010
                                                 first_table->table,
 
1011
                                                 &lex->field_list,
 
1012
                                                 &lex->update_list,
 
1013
                                                 &lex->value_list,
 
1014
                                                 lex->duplicates,
 
1015
                                                 lex->ignore)))
 
1016
      {
 
1017
        res= handle_select(session, lex, sel_result, OPTION_SETUP_TABLES_DONE);
 
1018
        /*
 
1019
          Invalidate the table in the query cache if something changed
 
1020
          after unlocking when changes become visible.
 
1021
          TODO: this is workaround. right way will be move invalidating in
 
1022
          the unlock procedure.
 
1023
        */
 
1024
        if (first_table->lock_type ==  TL_WRITE_CONCURRENT_INSERT &&
 
1025
            session->lock)
 
1026
        {
 
1027
          /* INSERT ... SELECT should invalidate only the very first table */
 
1028
          TableList *save_table= first_table->next_local;
 
1029
          first_table->next_local= 0;
 
1030
          first_table->next_local= save_table;
 
1031
        }
 
1032
        delete sel_result;
 
1033
      }
 
1034
      /* revert changes for SP */
 
1035
      select_lex->table_list.first= (unsigned char*) first_table;
 
1036
    }
 
1037
 
 
1038
    break;
 
1039
  }
 
1040
  case SQLCOM_TRUNCATE:
 
1041
    if (! session->endActiveTransaction())
 
1042
    {
 
1043
      res= -1;
 
1044
      break;
 
1045
    }
 
1046
    assert(first_table == all_tables && first_table != 0);
 
1047
    /*
 
1048
      Don't allow this within a transaction because we want to use
 
1049
      re-generate table
 
1050
    */
 
1051
    if (session->locked_tables || session->active_transaction())
 
1052
    {
 
1053
      my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
 
1054
                 ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
 
1055
      goto error;
 
1056
    }
 
1057
 
 
1058
    res= mysql_truncate(session, first_table, 0);
 
1059
 
 
1060
    break;
 
1061
  case SQLCOM_DELETE:
 
1062
  {
 
1063
    assert(first_table == all_tables && first_table != 0);
 
1064
    assert(select_lex->offset_limit == 0);
 
1065
    unit->set_limit(select_lex);
 
1066
 
 
1067
    if (!session->locked_tables &&
 
1068
        !(need_start_waiting= !wait_if_global_read_lock(session, 0, 1)))
 
1069
    {
 
1070
      res= 1;
 
1071
      break;
 
1072
    }
 
1073
 
 
1074
    res = mysql_delete(session, all_tables, select_lex->where,
 
1075
                       &select_lex->order_list,
 
1076
                       unit->select_limit_cnt, select_lex->options,
 
1077
                       false);
 
1078
    break;
 
1079
  }
 
1080
  case SQLCOM_DELETE_MULTI:
 
1081
  {
 
1082
    assert(first_table == all_tables && first_table != 0);
 
1083
    TableList *aux_tables=
 
1084
      (TableList *)session->lex->auxiliary_table_list.first;
 
1085
    multi_delete *del_result;
 
1086
 
 
1087
    if (!session->locked_tables &&
 
1088
        !(need_start_waiting= !wait_if_global_read_lock(session, 0, 1)))
 
1089
    {
 
1090
      res= 1;
 
1091
      break;
 
1092
    }
 
1093
 
 
1094
    if ((res= multi_delete_precheck(session, all_tables)))
 
1095
      break;
 
1096
 
 
1097
    /* condition will be true on SP re-excuting */
 
1098
    if (select_lex->item_list.elements != 0)
 
1099
      select_lex->item_list.empty();
 
1100
    if (session->add_item_to_list(new Item_null()))
 
1101
      goto error;
 
1102
 
 
1103
    session->set_proc_info("init");
 
1104
    if ((res= open_and_lock_tables(session, all_tables)))
 
1105
      break;
 
1106
 
 
1107
    if ((res= mysql_multi_delete_prepare(session)))
 
1108
      goto error;
 
1109
 
 
1110
    if (!session->is_fatal_error &&
 
1111
        (del_result= new multi_delete(aux_tables, lex->table_count)))
 
1112
    {
 
1113
      res= mysql_select(session, &select_lex->ref_pointer_array,
 
1114
                        select_lex->get_table_list(),
 
1115
                        select_lex->with_wild,
 
1116
                        select_lex->item_list,
 
1117
                        select_lex->where,
 
1118
                        0, (order_st *)NULL, (order_st *)NULL, (Item *)NULL,
 
1119
                        select_lex->options | session->options | SELECT_NO_JOIN_CACHE | SELECT_NO_UNLOCK | OPTION_SETUP_TABLES_DONE,
 
1120
                        del_result, unit, select_lex);
 
1121
      res|= session->is_error();
 
1122
      if (res)
 
1123
        del_result->abort();
 
1124
      delete del_result;
 
1125
    }
 
1126
    else
 
1127
      res= true;                                // Error
 
1128
    break;
 
1129
  }
 
1130
  case SQLCOM_DROP_TABLE:
 
1131
  {
 
1132
    assert(first_table == all_tables && first_table != 0);
 
1133
    if (!lex->drop_temporary)
 
1134
    {
 
1135
      if (! session->endActiveTransaction())
 
1136
        goto error;
 
1137
    }
 
1138
    else
 
1139
    {
 
1140
      /* So that DROP TEMPORARY TABLE gets to binlog at commit/rollback */
 
1141
      session->options|= OPTION_KEEP_LOG;
 
1142
    }
 
1143
    /* DDL and binlog write order protected by LOCK_open */
 
1144
    res= mysql_rm_table(session, first_table, lex->drop_if_exists, lex->drop_temporary);
 
1145
  }
 
1146
  break;
 
1147
  case SQLCOM_SHOW_PROCESSLIST:
 
1148
    mysqld_list_processes(session, NULL, lex->verbose);
 
1149
    break;
 
1150
  case SQLCOM_SHOW_ENGINE_LOGS:
 
1151
    {
 
1152
      res= ha_show_status(session, lex->create_info.db_type, HA_ENGINE_LOGS);
 
1153
      break;
 
1154
    }
 
1155
  case SQLCOM_CHANGE_DB:
 
1156
  {
 
1157
    LEX_STRING db_str= { (char *) select_lex->db, strlen(select_lex->db) };
 
1158
 
 
1159
    if (!mysql_change_db(session, &db_str, false))
 
1160
      session->my_ok();
 
1161
 
 
1162
    break;
 
1163
  }
 
1164
 
 
1165
  case SQLCOM_LOAD:
 
1166
  {
 
1167
    assert(first_table == all_tables && first_table != 0);
 
1168
    res= mysql_load(session, lex->exchange, first_table, lex->field_list,
 
1169
                    lex->update_list, lex->value_list, lex->duplicates, lex->ignore);
 
1170
    break;
 
1171
  }
 
1172
 
 
1173
  case SQLCOM_SET_OPTION:
 
1174
  {
 
1175
    List<set_var_base> *lex_var_list= &lex->var_list;
 
1176
 
 
1177
    if (lex->autocommit && ! session->endActiveTransaction())
 
1178
      goto error;
 
1179
 
 
1180
    if (open_and_lock_tables(session, all_tables))
 
1181
      goto error;
 
1182
    if (!(res= sql_set_variables(session, lex_var_list)))
 
1183
    {
 
1184
      session->my_ok();
 
1185
    }
 
1186
    else
 
1187
    {
 
1188
      /*
 
1189
        We encountered some sort of error, but no message was sent.
 
1190
        Send something semi-generic here since we don't know which
 
1191
        assignment in the list caused the error.
 
1192
      */
 
1193
      if (!session->is_error())
 
1194
        my_error(ER_WRONG_ARGUMENTS,MYF(0),"SET");
 
1195
      goto error;
 
1196
    }
 
1197
 
 
1198
    break;
 
1199
  }
 
1200
 
 
1201
  case SQLCOM_UNLOCK_TABLES:
 
1202
    /*
 
1203
      It is critical for mysqldump --single-transaction --master-data that
 
1204
      UNLOCK TABLES does not implicitely commit a connection which has only
 
1205
      done FLUSH TABLES WITH READ LOCK + BEGIN. If this assumption becomes
 
1206
      false, mysqldump will not work.
 
1207
    */
 
1208
    unlock_locked_tables(session);
 
1209
    if (session->options & OPTION_TABLE_LOCK)
 
1210
    {
 
1211
      (void) session->endActiveTransaction();
 
1212
      session->options&= ~(OPTION_TABLE_LOCK);
 
1213
    }
 
1214
    if (session->global_read_lock)
 
1215
      unlock_global_read_lock(session);
 
1216
    session->my_ok();
 
1217
    break;
 
1218
  case SQLCOM_LOCK_TABLES:
 
1219
    /*
 
1220
      We try to take transactional locks if
 
1221
      - only transactional locks are requested (lex->lock_transactional) and
 
1222
      - no non-transactional locks exist (!session->locked_tables).
 
1223
    */
 
1224
    if (lex->lock_transactional && !session->locked_tables)
 
1225
    {
 
1226
      int rc;
 
1227
      /*
 
1228
        All requested locks are transactional and no non-transactional
 
1229
        locks exist.
 
1230
      */
 
1231
      if ((rc= try_transactional_lock(session, all_tables)) == -1)
 
1232
        goto error;
 
1233
      if (rc == 0)
 
1234
      {
 
1235
        session->my_ok();
 
1236
        break;
 
1237
      }
 
1238
      /*
 
1239
        Non-transactional locking has been requested or
 
1240
        non-transactional locks exist already or transactional locks are
 
1241
        not supported by all storage engines. Take non-transactional
 
1242
        locks.
 
1243
      */
 
1244
    }
 
1245
    /*
 
1246
      One or more requested locks are non-transactional and/or
 
1247
      non-transactional locks exist or a storage engine does not support
 
1248
      transactional locks. Check if at least one transactional lock is
 
1249
      requested. If yes, warn about the conversion to non-transactional
 
1250
      locks or abort in strict mode.
 
1251
    */
 
1252
    if (check_transactional_lock(session, all_tables))
 
1253
      goto error;
 
1254
    unlock_locked_tables(session);
 
1255
    /* we must end the trasaction first, regardless of anything */
 
1256
    if (! session->endActiveTransaction())
 
1257
      goto error;
 
1258
    session->in_lock_tables=1;
 
1259
    session->options|= OPTION_TABLE_LOCK;
 
1260
 
 
1261
    if (!(res= simple_open_n_lock_tables(session, all_tables)))
 
1262
    {
 
1263
      session->locked_tables=session->lock;
 
1264
      session->lock=0;
 
1265
      (void) set_handler_table_locks(session, all_tables, false);
 
1266
      session->my_ok();
 
1267
    }
 
1268
    else
 
1269
    {
 
1270
      /*
 
1271
        Need to end the current transaction, so the storage engine (InnoDB)
 
1272
        can free its locks if LOCK TABLES locked some tables before finding
 
1273
        that it can't lock a table in its list
 
1274
      */
 
1275
      ha_autocommit_or_rollback(session, 1);
 
1276
      (void) session->endActiveTransaction();
 
1277
      session->options&= ~(OPTION_TABLE_LOCK);
 
1278
    }
 
1279
    session->in_lock_tables=0;
 
1280
    break;
 
1281
  case SQLCOM_CREATE_DB:
 
1282
  {
 
1283
    /*
 
1284
      As mysql_create_db() may modify HA_CREATE_INFO structure passed to
 
1285
      it, we need to use a copy of LEX::create_info to make execution
 
1286
      prepared statement- safe.
 
1287
    */
 
1288
    HA_CREATE_INFO create_info(lex->create_info);
 
1289
    if (! session->endActiveTransaction())
 
1290
    {
 
1291
      res= -1;
 
1292
      break;
 
1293
    }
 
1294
    char *alias;
 
1295
    if (!(alias=session->strmake(lex->name.str, lex->name.length)) ||
 
1296
        check_db_name(&lex->name))
 
1297
    {
 
1298
      my_error(ER_WRONG_DB_NAME, MYF(0), lex->name.str);
 
1299
      break;
 
1300
    }
 
1301
    res= mysql_create_db(session,(lower_case_table_names == 2 ? alias :
 
1302
                              lex->name.str), &create_info, 0);
 
1303
    break;
 
1304
  }
 
1305
  case SQLCOM_DROP_DB:
 
1306
  {
 
1307
    if (! session->endActiveTransaction())
 
1308
    {
 
1309
      res= -1;
 
1310
      break;
 
1311
    }
 
1312
    if (check_db_name(&lex->name))
 
1313
    {
 
1314
      my_error(ER_WRONG_DB_NAME, MYF(0), lex->name.str);
 
1315
      break;
 
1316
    }
 
1317
    if (session->locked_tables || session->active_transaction())
 
1318
    {
 
1319
      my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
 
1320
                 ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
 
1321
      goto error;
 
1322
    }
 
1323
    res= mysql_rm_db(session, lex->name.str, lex->drop_if_exists, 0);
 
1324
    break;
 
1325
  }
 
1326
  case SQLCOM_ALTER_DB:
 
1327
  {
 
1328
    LEX_STRING *db= &lex->name;
 
1329
    HA_CREATE_INFO create_info(lex->create_info);
 
1330
    if (check_db_name(db))
 
1331
    {
 
1332
      my_error(ER_WRONG_DB_NAME, MYF(0), db->str);
 
1333
      break;
 
1334
    }
 
1335
    if (session->locked_tables || session->active_transaction())
 
1336
    {
 
1337
      my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
 
1338
                 ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
 
1339
      goto error;
 
1340
    }
 
1341
    res= mysql_alter_db(session, db->str, &create_info);
 
1342
    break;
 
1343
  }
 
1344
  case SQLCOM_SHOW_CREATE_DB:
 
1345
  {
 
1346
    if (check_db_name(&lex->name))
 
1347
    {
 
1348
      my_error(ER_WRONG_DB_NAME, MYF(0), lex->name.str);
 
1349
      break;
 
1350
    }
 
1351
    res= mysqld_show_create_db(session, lex->name.str, &lex->create_info);
 
1352
    break;
 
1353
  }
 
1354
  case SQLCOM_FLUSH:
 
1355
  {
 
1356
    bool write_to_binlog;
 
1357
 
 
1358
    /*
 
1359
      reload_cache() will tell us if we are allowed to write to the
 
1360
      binlog or not.
 
1361
    */
 
1362
    if (!reload_cache(session, lex->type, first_table, &write_to_binlog))
 
1363
    {
 
1364
      /*
 
1365
        We WANT to write and we CAN write.
 
1366
        ! we write after unlocking the table.
 
1367
      */
 
1368
      /*
 
1369
        Presumably, RESET and binlog writing doesn't require synchronization
 
1370
      */
 
1371
      write_bin_log(session, false, session->query, session->query_length);
 
1372
      session->my_ok();
 
1373
    }
 
1374
 
 
1375
    break;
 
1376
  }
 
1377
  case SQLCOM_KILL:
 
1378
  {
 
1379
    Item *it= (Item *)lex->value_list.head();
 
1380
 
 
1381
    if ((!it->fixed && it->fix_fields(lex->session, &it)) || it->check_cols(1))
 
1382
    {
 
1383
      my_message(ER_SET_CONSTANTS_ONLY, ER(ER_SET_CONSTANTS_ONLY),
 
1384
                 MYF(0));
 
1385
      goto error;
 
1386
    }
 
1387
    sql_kill(session, (ulong)it->val_int(), lex->type & ONLY_KILL_QUERY);
 
1388
    break;
 
1389
  }
 
1390
  case SQLCOM_BEGIN:
 
1391
    if (session->transaction.xid_state.xa_state != XA_NOTR)
 
1392
    {
 
1393
      my_error(ER_XAER_RMFAIL, MYF(0),
 
1394
               xa_state_names[session->transaction.xid_state.xa_state]);
 
1395
      break;
 
1396
    }
 
1397
    /*
 
1398
      Breakpoints for backup testing.
 
1399
    */
 
1400
    if (! session->startTransaction())
 
1401
      goto error;
 
1402
    session->my_ok();
 
1403
    break;
 
1404
  case SQLCOM_COMMIT:
 
1405
    if (! session->endTransaction(lex->tx_release ? COMMIT_RELEASE : lex->tx_chain ? COMMIT_AND_CHAIN : COMMIT))
 
1406
      goto error;
 
1407
    session->my_ok();
 
1408
    break;
 
1409
  case SQLCOM_ROLLBACK:
 
1410
    if (! session->endTransaction(lex->tx_release ? ROLLBACK_RELEASE : lex->tx_chain ? ROLLBACK_AND_CHAIN : ROLLBACK))
 
1411
      goto error;
 
1412
    session->my_ok();
 
1413
    break;
 
1414
  case SQLCOM_RELEASE_SAVEPOINT:
 
1415
  {
 
1416
    SAVEPOINT *sv;
 
1417
    for (sv=session->transaction.savepoints; sv; sv=sv->prev)
 
1418
    {
 
1419
      if (my_strnncoll(system_charset_info,
 
1420
                       (unsigned char *)lex->ident.str, lex->ident.length,
 
1421
                       (unsigned char *)sv->name, sv->length) == 0)
 
1422
        break;
 
1423
    }
 
1424
    if (sv)
 
1425
    {
 
1426
      if (ha_release_savepoint(session, sv))
 
1427
        res= true; // cannot happen
 
1428
      else
 
1429
        session->my_ok();
 
1430
      session->transaction.savepoints=sv->prev;
 
1431
    }
 
1432
    else
 
1433
      my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "SAVEPOINT", lex->ident.str);
 
1434
    break;
 
1435
  }
 
1436
  case SQLCOM_ROLLBACK_TO_SAVEPOINT:
 
1437
  {
 
1438
    SAVEPOINT *sv;
 
1439
    for (sv=session->transaction.savepoints; sv; sv=sv->prev)
 
1440
    {
 
1441
      if (my_strnncoll(system_charset_info,
 
1442
                       (unsigned char *)lex->ident.str, lex->ident.length,
 
1443
                       (unsigned char *)sv->name, sv->length) == 0)
 
1444
        break;
 
1445
    }
 
1446
    if (sv)
 
1447
    {
 
1448
      if (ha_rollback_to_savepoint(session, sv))
 
1449
        res= true; // cannot happen
 
1450
      else
 
1451
      {
 
1452
        if ((session->options & OPTION_KEEP_LOG) || session->transaction.all.modified_non_trans_table)
 
1453
          push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
1454
                       ER_WARNING_NOT_COMPLETE_ROLLBACK,
 
1455
                       ER(ER_WARNING_NOT_COMPLETE_ROLLBACK));
 
1456
        session->my_ok();
 
1457
      }
 
1458
      session->transaction.savepoints=sv;
 
1459
    }
 
1460
    else
 
1461
      my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "SAVEPOINT", lex->ident.str);
 
1462
    break;
 
1463
  }
 
1464
  case SQLCOM_SAVEPOINT:
 
1465
    if (!(session->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) || !opt_using_transactions)
 
1466
      session->my_ok();
 
1467
    else
 
1468
    {
 
1469
      SAVEPOINT **sv, *newsv;
 
1470
      for (sv=&session->transaction.savepoints; *sv; sv=&(*sv)->prev)
 
1471
      {
 
1472
        if (my_strnncoll(system_charset_info,
 
1473
                         (unsigned char *)lex->ident.str, lex->ident.length,
 
1474
                         (unsigned char *)(*sv)->name, (*sv)->length) == 0)
 
1475
          break;
 
1476
      }
 
1477
      if (*sv) /* old savepoint of the same name exists */
 
1478
      {
 
1479
        newsv=*sv;
 
1480
        ha_release_savepoint(session, *sv); // it cannot fail
 
1481
        *sv=(*sv)->prev;
 
1482
      }
 
1483
      else if ((newsv=(SAVEPOINT *) alloc_root(&session->transaction.mem_root,
 
1484
                                               savepoint_alloc_size)) == 0)
 
1485
      {
 
1486
        my_error(ER_OUT_OF_RESOURCES, MYF(0));
 
1487
        break;
 
1488
      }
 
1489
      newsv->name=strmake_root(&session->transaction.mem_root,
 
1490
                               lex->ident.str, lex->ident.length);
 
1491
      newsv->length=lex->ident.length;
 
1492
      /*
 
1493
        if we'll get an error here, don't add new savepoint to the list.
 
1494
        we'll lose a little bit of memory in transaction mem_root, but it'll
 
1495
        be free'd when transaction ends anyway
 
1496
      */
 
1497
      if (ha_savepoint(session, newsv))
 
1498
        res= true;
 
1499
      else
 
1500
      {
 
1501
        newsv->prev=session->transaction.savepoints;
 
1502
        session->transaction.savepoints=newsv;
 
1503
        session->my_ok();
 
1504
      }
 
1505
    }
 
1506
    break;
 
1507
  default:
 
1508
    assert(0);                             /* Impossible */
 
1509
    session->my_ok();
 
1510
    break;
 
1511
  }
480
1512
  session->set_proc_info("query end");
 
1513
 
481
1514
  /*
482
1515
    The return value for ROW_COUNT() is "implementation dependent" if the
483
1516
    statement is not DELETE, INSERT or UPDATE, but -1 is what JDBC and ODBC
484
1517
    wants. We also keep the last value in case of SQLCOM_CALL or
485
1518
    SQLCOM_EXECUTE.
486
1519
  */
487
 
  if (! (sql_command_flags[lex->sql_command].test(CF_BIT_HAS_ROW_COUNT)))
488
 
  {
 
1520
  if (!(sql_command_flags[lex->sql_command].test(CF_BIT_HAS_ROW_COUNT)))
489
1521
    session->row_count_func= -1;
 
1522
 
 
1523
  goto finish;
 
1524
 
 
1525
error:
 
1526
  res= true;
 
1527
 
 
1528
finish:
 
1529
  if (need_start_waiting)
 
1530
  {
 
1531
    /*
 
1532
      Release the protection against the global read lock and wake
 
1533
      everyone, who might want to set a global read lock.
 
1534
    */
 
1535
    start_waiting_global_read_lock(session);
490
1536
  }
491
 
 
492
 
  return (res || session->is_error());
 
1537
  return(res || session->is_error());
493
1538
}
 
1539
 
494
1540
bool execute_sqlcom_select(Session *session, TableList *all_tables)
495
1541
{
496
1542
  LEX   *lex= session->lex;
503
1549
      param->select_limit=
504
1550
        new Item_int((uint64_t) session->variables.select_limit);
505
1551
  }
506
 
  if (not (res= session->openTablesLock(all_tables)))
 
1552
  if (!(res= open_and_lock_tables(session, all_tables)))
507
1553
  {
508
1554
    if (lex->describe)
509
1555
    {
514
1560
        even if the query itself redirects the output.
515
1561
      */
516
1562
      if (!(result= new select_send()))
517
 
        return true;
 
1563
        return true;                               /* purecov: inspected */
518
1564
      session->send_explain_fields(result);
519
 
      optimizer::ExplainPlan planner;
520
 
      res= planner.explainUnion(session, &session->lex->unit, result);
 
1565
      res= mysql_explain_union(session, &session->lex->unit, result);
521
1566
      if (lex->describe & DESCRIBE_EXTENDED)
522
1567
      {
523
1568
        char buff[1024];
537
1582
    else
538
1583
    {
539
1584
      if (!result && !(result= new select_send()))
540
 
        return true;
541
 
 
542
 
      /* Init the Query Cache plugin */
543
 
      plugin::QueryCache::prepareResultset(session); 
 
1585
        return true;                               /* purecov: inspected */
544
1586
      res= handle_select(session, lex, result, 0);
545
 
      /* Send the Resultset to the cache */
546
 
      plugin::QueryCache::setResultset(session); 
547
 
 
548
1587
      if (result != lex->result)
549
1588
        delete result;
550
1589
    }
622
1661
  if (move_down)
623
1662
  {
624
1663
    Select_Lex_Unit *unit;
 
1664
    lex->subqueries= true;
625
1665
    /* first select_lex of subselect or derived table */
626
1666
    if (!(unit= new (session->mem_root) Select_Lex_Unit()))
627
1667
      return(1);
698
1738
  */
699
1739
  if ((var= get_system_var(session, OPT_SESSION, tmp, null_lex_string)))
700
1740
  {
701
 
    end+= snprintf(buff, sizeof(buff), "@@session.%s", var_name);
 
1741
    end+= sprintf(buff, "@@session.%s", var_name);
702
1742
    var->set_name(buff, end-buff, system_charset_info);
703
1743
    session->add_item_to_list(var);
704
1744
  }
706
1746
}
707
1747
 
708
1748
 
 
1749
void mysql_init_multi_delete(LEX *lex)
 
1750
{
 
1751
  lex->sql_command=  SQLCOM_DELETE_MULTI;
 
1752
  mysql_init_select(lex);
 
1753
  lex->select_lex.select_limit= 0;
 
1754
  lex->unit.select_limit_cnt= HA_POS_ERROR;
 
1755
  lex->select_lex.table_list.save_and_clear(&lex->auxiliary_table_list);
 
1756
  lex->lock_option= TL_READ;
 
1757
  lex->query_tables= 0;
 
1758
  lex->query_tables_last= &lex->query_tables;
 
1759
}
 
1760
 
 
1761
 
709
1762
/**
710
1763
  Parse a query.
711
1764
 
712
1765
  @param       session     Current thread
713
1766
  @param       inBuf   Begining of the query text
714
1767
  @param       length  Length of the query text
 
1768
  @param[out]  found_semicolon For multi queries, position of the character of
 
1769
                               the next query in the query text.
715
1770
*/
716
1771
 
717
 
void mysql_parse(Session *session, const char *inBuf, uint32_t length)
 
1772
void mysql_parse(Session *session, const char *inBuf, uint32_t length,
 
1773
                 const char ** found_semicolon)
718
1774
{
719
 
  boost::posix_time::ptime start_time=boost::posix_time::microsec_clock::local_time();
720
 
  session->lex->start(session);
721
 
 
 
1775
  /*
 
1776
    Warning.
 
1777
    The purpose of query_cache_send_result_to_client() is to lookup the
 
1778
    query in the query cache first, to avoid parsing and executing it.
 
1779
    So, the natural implementation would be to:
 
1780
    - first, call query_cache_send_result_to_client,
 
1781
    - second, if caching failed, initialise the lexical and syntactic parser.
 
1782
    The problem is that the query cache depends on a clean initialization
 
1783
    of (among others) lex->safe_to_cache_query and session->server_status,
 
1784
    which are reset respectively in
 
1785
    - lex_start()
 
1786
    - mysql_reset_session_for_next_command()
 
1787
    So, initializing the lexical analyser *before* using the query cache
 
1788
    is required for the cache to work properly.
 
1789
    FIXME: cleanup the dependencies in the code to simplify this.
 
1790
  */
 
1791
  lex_start(session);
722
1792
  session->reset_for_next_command();
723
 
  /* Check if the Query is Cached if and return true if yes
724
 
   * TODO the plugin has to make sure that the query is cacheble
725
 
   * by setting the query_safe_cache param to TRUE
726
 
   */
727
 
  bool res= true;
728
 
  if (plugin::QueryCache::isCached(session))
729
 
  {
730
 
    res= plugin::QueryCache::sendCachedResultset(session);
731
 
  }
732
 
  if (not res)
733
 
  {
734
 
    return;
735
 
  }
736
 
  LEX *lex= session->lex;
737
 
  Lex_input_stream lip(session, inBuf, length);
738
 
  bool err= parse_sql(session, &lip);
739
 
  if (!err)
740
 
  {
 
1793
 
 
1794
  {
 
1795
    LEX *lex= session->lex;
 
1796
 
 
1797
    Lex_input_stream lip(session, inBuf, length);
 
1798
 
 
1799
    bool err= parse_sql(session, &lip);
 
1800
    *found_semicolon= lip.found_semicolon;
 
1801
 
 
1802
    if (!err)
741
1803
    {
742
 
      if (not session->is_error())
743
1804
      {
744
 
        DRIZZLE_QUERY_EXEC_START(session->getQueryString()->c_str(),
745
 
                                 session->thread_id,
746
 
                                 const_cast<const char *>(session->schema()->c_str()));
747
 
        // Implement Views here --Brian
748
 
        /* Actually execute the query */
749
 
        try 
750
 
        {
 
1805
        if (! session->is_error())
 
1806
        {
 
1807
          /*
 
1808
            Binlog logs a string starting from session->query and having length
 
1809
            session->query_length; so we set session->query_length correctly (to not
 
1810
            log several statements in one event, when we executed only first).
 
1811
            We set it to not see the ';' (otherwise it would get into binlog
 
1812
            and Query_log_event::print() would give ';;' output).
 
1813
            This also helps display only the current query in SHOW
 
1814
            PROCESSLIST.
 
1815
            Note that we don't need LOCK_thread_count to modify query_length.
 
1816
          */
 
1817
          if (*found_semicolon &&
 
1818
              (session->query_length= (ulong)(*found_semicolon - session->query)))
 
1819
            session->query_length--;
 
1820
          /* Actually execute the query */
751
1821
          mysql_execute_command(session);
752
 
        }
753
 
        catch (...)
754
 
        {
755
 
          // Just try to catch any random failures that could have come
756
 
          // during execution.
757
 
          unireg_abort(1);
758
 
        }
759
 
        DRIZZLE_QUERY_EXEC_DONE(0);
 
1822
        }
760
1823
      }
761
1824
    }
762
 
  }
763
 
  else
764
 
  {
765
 
    assert(session->is_error());
766
 
  }
767
 
  lex->unit.cleanup();
768
 
  session->set_proc_info("freeing items");
769
 
  session->end_statement();
770
 
  session->cleanup_after_query();
771
 
  boost::posix_time::ptime end_time=boost::posix_time::microsec_clock::local_time();
772
 
  session->status_var.execution_time_nsec+=(end_time-start_time).total_microseconds();
 
1825
    else
 
1826
    {
 
1827
      assert(session->is_error());
 
1828
    }
 
1829
    lex->unit.cleanup();
 
1830
    session->set_proc_info("freeing items");
 
1831
    session->end_statement();
 
1832
    session->cleanup_after_query();
 
1833
    assert(session->change_list.is_empty());
 
1834
  }
 
1835
 
 
1836
  return;
773
1837
}
774
1838
 
775
1839
 
788
1852
                       Item *default_value, Item *on_update_value,
789
1853
                       LEX_STRING *comment,
790
1854
                       char *change,
791
 
                       List<String> *interval_list, const CHARSET_INFO * const cs)
 
1855
                       List<String> *interval_list, const CHARSET_INFO * const cs,
 
1856
                       virtual_column_info *vcol_info)
792
1857
{
793
 
  register CreateField *new_field;
 
1858
  register Create_field *new_field;
794
1859
  LEX  *lex= session->lex;
795
 
  statement::AlterTable *statement= (statement::AlterTable *)lex->statement;
796
1860
 
797
1861
  if (check_identifier_name(field_name, ER_TOO_LONG_IDENT))
798
 
    return true;
 
1862
    return(1);                          /* purecov: inspected */
799
1863
 
800
1864
  if (type_modifier & PRI_KEY_FLAG)
801
1865
  {
804
1868
    key= new Key(Key::PRIMARY, null_lex_str,
805
1869
                      &default_key_create_info,
806
1870
                      0, lex->col_list);
807
 
    statement->alter_info.key_list.push_back(key);
 
1871
    lex->alter_info.key_list.push_back(key);
808
1872
    lex->col_list.empty();
809
1873
  }
810
1874
  if (type_modifier & (UNIQUE_FLAG | UNIQUE_KEY_FLAG))
814
1878
    key= new Key(Key::UNIQUE, null_lex_str,
815
1879
                 &default_key_create_info, 0,
816
1880
                 lex->col_list);
817
 
    statement->alter_info.key_list.push_back(key);
 
1881
    lex->alter_info.key_list.push_back(key);
818
1882
    lex->col_list.empty();
819
1883
  }
820
1884
 
832
1896
         type == DRIZZLE_TYPE_TIMESTAMP))
833
1897
    {
834
1898
      my_error(ER_INVALID_DEFAULT, MYF(0), field_name->str);
835
 
      return true;
 
1899
      return(1);
836
1900
    }
837
1901
    else if (default_value->type() == Item::NULL_ITEM)
838
1902
    {
841
1905
          NOT_NULL_FLAG)
842
1906
      {
843
1907
        my_error(ER_INVALID_DEFAULT, MYF(0), field_name->str);
844
 
        return true;
 
1908
        return(1);
845
1909
      }
846
1910
    }
847
1911
    else if (type_modifier & AUTO_INCREMENT_FLAG)
848
1912
    {
849
1913
      my_error(ER_INVALID_DEFAULT, MYF(0), field_name->str);
850
 
      return true;
 
1914
      return(1);
851
1915
    }
852
1916
  }
853
1917
 
854
1918
  if (on_update_value && type != DRIZZLE_TYPE_TIMESTAMP)
855
1919
  {
856
1920
    my_error(ER_INVALID_ON_UPDATE, MYF(0), field_name->str);
857
 
    return true;
 
1921
    return(1);
858
1922
  }
859
1923
 
860
 
  if (!(new_field= new CreateField()) ||
 
1924
  if (!(new_field= new Create_field()) ||
861
1925
      new_field->init(session, field_name->str, type, length, decimals, type_modifier,
862
1926
                      default_value, on_update_value, comment, change,
863
 
                      interval_list, cs, 0, column_format))
864
 
    return true;
 
1927
                      interval_list, cs, 0, column_format,
 
1928
                      vcol_info))
 
1929
    return(1);
865
1930
 
866
 
  statement->alter_info.create_list.push_back(new_field);
 
1931
  lex->alter_info.create_list.push_back(new_field);
867
1932
  lex->last_field=new_field;
868
 
 
869
 
  return false;
 
1933
  return(0);
870
1934
}
871
1935
 
872
1936
 
878
1942
}
879
1943
 
880
1944
/**
 
1945
  save order by and tables in own lists.
 
1946
*/
 
1947
 
 
1948
bool add_to_list(Session *session, SQL_LIST &list,Item *item,bool asc)
 
1949
{
 
1950
  order_st *order;
 
1951
  if (!(order = (order_st *) session->alloc(sizeof(order_st))))
 
1952
    return(1);
 
1953
  order->item_ptr= item;
 
1954
  order->item= &order->item_ptr;
 
1955
  order->asc = asc;
 
1956
  order->free_me=0;
 
1957
  order->used=0;
 
1958
  order->counter_used= 0;
 
1959
  list.link_in_list((unsigned char*) order,(unsigned char**) &order->next);
 
1960
  return(0);
 
1961
}
 
1962
 
 
1963
 
 
1964
/**
881
1965
  Add a table to list of used tables.
882
1966
 
883
1967
  @param table          Table to add
897
1981
*/
898
1982
 
899
1983
TableList *Select_Lex::add_table_to_list(Session *session,
900
 
                                                             Table_ident *table,
901
 
                                                             LEX_STRING *alias,
902
 
                                                             const bitset<NUM_OF_TABLE_OPTIONS>& table_options,
903
 
                                                             thr_lock_type lock_type,
904
 
                                                             List<Index_hint> *index_hints_arg,
905
 
                                         LEX_STRING *option)
 
1984
                                             Table_ident *table,
 
1985
                                             LEX_STRING *alias,
 
1986
                                             uint32_t table_options,
 
1987
                                             thr_lock_type lock_type,
 
1988
                                             List<Index_hint> *index_hints_arg,
 
1989
                                             LEX_STRING *option)
906
1990
{
907
 
  TableList *ptr;
 
1991
  register TableList *ptr;
908
1992
  TableList *previous_table_ref; /* The table preceding the current one. */
909
1993
  char *alias_str;
910
1994
  LEX *lex= session->lex;
911
1995
 
912
1996
  if (!table)
913
 
    return NULL;                                // End of memory
 
1997
    return(0);                          // End of memory
914
1998
  alias_str= alias ? alias->str : table->table.str;
915
 
  if (! table_options.test(TL_OPTION_ALIAS) &&
 
1999
  if (!test(table_options & TL_OPTION_ALIAS) &&
916
2000
      check_table_name(table->table.str, table->table.length))
917
2001
  {
918
2002
    my_error(ER_WRONG_TABLE_NAME, MYF(0), table->table.str);
919
 
    return NULL;
 
2003
    return(0);
920
2004
  }
921
2005
 
922
 
  if (table->is_derived_table() == false && table->db.str)
 
2006
  if (table->is_derived_table() == false && table->db.str &&
 
2007
      check_db_name(&table->db))
923
2008
  {
924
 
    my_casedn_str(files_charset_info, table->db.str);
925
 
 
926
 
    SchemaIdentifier schema_identifier(string(table->db.str));
927
 
    if (not check_db_name(session, schema_identifier))
928
 
    {
929
 
 
930
 
      my_error(ER_WRONG_DB_NAME, MYF(0), table->db.str);
931
 
      return NULL;
932
 
    }
 
2009
    my_error(ER_WRONG_DB_NAME, MYF(0), table->db.str);
 
2010
    return(0);
933
2011
  }
934
2012
 
935
2013
  if (!alias)                                   /* Alias is case sensitive */
938
2016
    {
939
2017
      my_message(ER_DERIVED_MUST_HAVE_ALIAS,
940
2018
                 ER(ER_DERIVED_MUST_HAVE_ALIAS), MYF(0));
941
 
      return NULL;
 
2019
      return(0);
942
2020
    }
943
2021
    if (!(alias_str= (char*) session->memdup(alias_str,table->table.length+1)))
944
 
      return NULL;
 
2022
      return(0);
945
2023
  }
946
2024
  if (!(ptr = (TableList *) session->calloc(sizeof(TableList))))
947
 
    return NULL;
948
 
 
 
2025
    return(0);                          /* purecov: inspected */
949
2026
  if (table->db.str)
950
2027
  {
951
 
    ptr->setIsFqtn(true);
952
 
    ptr->setSchemaName(table->db.str);
 
2028
    ptr->is_fqtn= true;
 
2029
    ptr->db= table->db.str;
953
2030
    ptr->db_length= table->db.length;
954
2031
  }
955
 
  else if (lex->copy_db_to(ptr->getSchemaNamePtr(), &ptr->db_length))
956
 
    return NULL;
 
2032
  else if (lex->copy_db_to(&ptr->db, &ptr->db_length))
 
2033
    return(0);
957
2034
  else
958
 
    ptr->setIsFqtn(false);
 
2035
    ptr->is_fqtn= false;
959
2036
 
960
2037
  ptr->alias= alias_str;
961
 
  ptr->setIsAlias(alias ? true : false);
962
 
  ptr->setTableName(table->table.str);
 
2038
  ptr->is_alias= alias ? true : false;
 
2039
  if (lower_case_table_names && table->table.length)
 
2040
    table->table.length= my_casedn_str(files_charset_info, table->table.str);
 
2041
  ptr->table_name=table->table.str;
963
2042
  ptr->table_name_length=table->table.length;
964
2043
  ptr->lock_type=   lock_type;
965
 
  ptr->force_index= table_options.test(TL_OPTION_FORCE_INDEX);
966
 
  ptr->ignore_leaves= table_options.test(TL_OPTION_IGNORE_LEAVES);
 
2044
  ptr->lock_timeout= -1;      /* default timeout */
 
2045
  ptr->lock_transactional= 1; /* allow transactional locks */
 
2046
  ptr->updating=    test(table_options & TL_OPTION_UPDATING);
 
2047
  ptr->force_index= test(table_options & TL_OPTION_FORCE_INDEX);
 
2048
  ptr->ignore_leaves= test(table_options & TL_OPTION_IGNORE_LEAVES);
967
2049
  ptr->derived=     table->sel;
 
2050
  if (!ptr->derived && !my_strcasecmp(system_charset_info, ptr->db,
 
2051
                                      INFORMATION_SCHEMA_NAME.c_str()))
 
2052
  {
 
2053
    ST_SCHEMA_TABLE *schema_table= find_schema_table(session, ptr->table_name);
 
2054
    if (!schema_table ||
 
2055
        (schema_table->hidden &&
 
2056
         ((sql_command_flags[lex->sql_command].test(CF_BIT_STATUS_COMMAND)) == 0 ||
 
2057
          /*
 
2058
            this check is used for show columns|keys from I_S hidden table
 
2059
          */
 
2060
          lex->sql_command == SQLCOM_SHOW_FIELDS ||
 
2061
          lex->sql_command == SQLCOM_SHOW_KEYS)))
 
2062
    {
 
2063
      my_error(ER_UNKNOWN_TABLE, MYF(0),
 
2064
               ptr->table_name, INFORMATION_SCHEMA_NAME.c_str());
 
2065
      return(0);
 
2066
    }
 
2067
    ptr->schema_table_name= ptr->table_name;
 
2068
    ptr->schema_table= schema_table;
 
2069
  }
968
2070
  ptr->select_lex=  lex->current_select;
 
2071
  ptr->cacheable_table= 1;
969
2072
  ptr->index_hints= index_hints_arg;
970
2073
  ptr->option= option ? option->str : 0;
971
2074
  /* check that used name is unique */
977
2080
         tables=tables->next_local)
978
2081
    {
979
2082
      if (!my_strcasecmp(table_alias_charset, alias_str, tables->alias) &&
980
 
          !strcasecmp(ptr->getSchemaName(), tables->getSchemaName()))
 
2083
          !strcmp(ptr->db, tables->db))
981
2084
      {
982
 
        my_error(ER_NONUNIQ_TABLE, MYF(0), alias_str);
983
 
        return NULL;
 
2085
        my_error(ER_NONUNIQ_TABLE, MYF(0), alias_str); /* purecov: tested */
 
2086
        return(0);                              /* purecov: tested */
984
2087
      }
985
2088
    }
986
2089
  }
1015
2118
  ptr->next_name_resolution_table= NULL;
1016
2119
  /* Link table in global list (all used tables) */
1017
2120
  lex->add_to_query_tables(ptr);
1018
 
  return ptr;
 
2121
  return(ptr);
1019
2122
}
1020
2123
 
1021
2124
 
1045
2148
 
1046
2149
  if (!(ptr= (TableList*) session->calloc(ALIGN_SIZE(sizeof(TableList))+
1047
2150
                                       sizeof(nested_join_st))))
1048
 
    return true;
1049
 
  ptr->setNestedJoin(((nested_join_st*) ((unsigned char*) ptr + ALIGN_SIZE(sizeof(TableList)))));
1050
 
  nested_join= ptr->getNestedJoin();
 
2151
    return(1);
 
2152
  nested_join= ptr->nested_join=
 
2153
    ((nested_join_st*) ((unsigned char*) ptr + ALIGN_SIZE(sizeof(TableList))));
 
2154
 
1051
2155
  join_list->push_front(ptr);
1052
 
  ptr->setEmbedding(embedding);
1053
 
  ptr->setJoinList(join_list);
 
2156
  ptr->embedding= embedding;
 
2157
  ptr->join_list= join_list;
1054
2158
  ptr->alias= (char*) "(nested_join)";
1055
2159
  embedding= ptr;
1056
2160
  join_list= &nested_join->join_list;
1057
2161
  join_list->empty();
1058
 
  return false;
 
2162
  return(0);
1059
2163
}
1060
2164
 
1061
2165
 
1080
2184
 
1081
2185
  assert(embedding);
1082
2186
  ptr= embedding;
1083
 
  join_list= ptr->getJoinList();
1084
 
  embedding= ptr->getEmbedding();
1085
 
  nested_join= ptr->getNestedJoin();
 
2187
  join_list= ptr->join_list;
 
2188
  embedding= ptr->embedding;
 
2189
  nested_join= ptr->nested_join;
1086
2190
  if (nested_join->join_list.elements == 1)
1087
2191
  {
1088
2192
    TableList *embedded= nested_join->join_list.head();
1089
2193
    join_list->pop();
1090
 
    embedded->setJoinList(join_list);
1091
 
    embedded->setEmbedding(embedding);
 
2194
    embedded->join_list= join_list;
 
2195
    embedded->embedding= embedding;
1092
2196
    join_list->push_front(embedded);
1093
2197
    ptr= embedded;
1094
2198
  }
1095
2199
  else if (nested_join->join_list.elements == 0)
1096
2200
  {
1097
2201
    join_list->pop();
1098
 
    ptr= NULL;                                     // return value
 
2202
    ptr= 0;                                     // return value
1099
2203
  }
1100
 
  return ptr;
 
2204
  return(ptr);
1101
2205
}
1102
2206
 
1103
2207
 
1121
2225
  List<TableList> *embedded_list;
1122
2226
 
1123
2227
  if (!(ptr= (TableList*) session->calloc(ALIGN_SIZE(sizeof(TableList))+
1124
 
                                          sizeof(nested_join_st))))
1125
 
    return NULL;
1126
 
  ptr->setNestedJoin(((nested_join_st*) ((unsigned char*) ptr + ALIGN_SIZE(sizeof(TableList)))));
1127
 
  nested_join= ptr->getNestedJoin();
1128
 
  ptr->setEmbedding(embedding);
1129
 
  ptr->setJoinList(join_list);
 
2228
                                       sizeof(nested_join_st))))
 
2229
    return(0);
 
2230
  nested_join= ptr->nested_join=
 
2231
    ((nested_join_st*) ((unsigned char*) ptr + ALIGN_SIZE(sizeof(TableList))));
 
2232
 
 
2233
  ptr->embedding= embedding;
 
2234
  ptr->join_list= join_list;
1130
2235
  ptr->alias= (char*) "(nest_last_join)";
1131
2236
  embedded_list= &nested_join->join_list;
1132
2237
  embedded_list->empty();
1134
2239
  for (uint32_t i=0; i < 2; i++)
1135
2240
  {
1136
2241
    TableList *table= join_list->pop();
1137
 
    table->setJoinList(embedded_list);
1138
 
    table->setEmbedding(ptr);
 
2242
    table->join_list= embedded_list;
 
2243
    table->embedding= ptr;
1139
2244
    embedded_list->push_back(table);
1140
2245
    if (table->natural_join)
1141
2246
    {
1150
2255
  }
1151
2256
  join_list->push_front(ptr);
1152
2257
  nested_join->used_tables= nested_join->not_null_tables= (table_map) 0;
1153
 
  return ptr;
 
2258
  return(ptr);
1154
2259
}
1155
2260
 
1156
2261
 
1171
2276
void Select_Lex::add_joined_table(TableList *table)
1172
2277
{
1173
2278
  join_list->push_front(table);
1174
 
  table->setJoinList(join_list);
1175
 
  table->setEmbedding(embedding);
 
2279
  table->join_list= join_list;
 
2280
  table->embedding= embedding;
 
2281
  return;
1176
2282
}
1177
2283
 
1178
2284
 
1216
2322
  join_list->push_front(tab1);
1217
2323
  tab1->outer_join|= JOIN_TYPE_RIGHT;
1218
2324
 
1219
 
  return tab1;
 
2325
  return(tab1);
1220
2326
}
1221
2327
 
1222
2328
/**
1232
2338
 
1233
2339
void Select_Lex::set_lock_for_tables(thr_lock_type lock_type)
1234
2340
{
 
2341
  bool for_update= lock_type >= TL_READ_NO_INSERT;
 
2342
 
1235
2343
  for (TableList *tables= (TableList*) table_list.first;
1236
2344
       tables;
1237
2345
       tables= tables->next_local)
1238
2346
  {
1239
2347
    tables->lock_type= lock_type;
 
2348
    tables->updating=  for_update;
1240
2349
  }
 
2350
  return;
1241
2351
}
1242
2352
 
1243
2353
 
1248
2358
    This object is created for any union construct containing a union
1249
2359
    operation and also for any single select union construct of the form
1250
2360
    @verbatim
1251
 
    (SELECT ... ORDER BY order_list [LIMIT n]) ORDER BY ...
 
2361
    (SELECT ... order_st BY order_list [LIMIT n]) order_st BY ...
1252
2362
    @endvarbatim
1253
2363
    or of the form
1254
2364
    @varbatim
1255
 
    (SELECT ... ORDER BY LIMIT n) ORDER BY ...
 
2365
    (SELECT ... order_st BY LIMIT n) order_st BY ...
1256
2366
    @endvarbatim
1257
2367
 
1258
2368
  @param session_arg               thread handle
1283
2393
  fake_select_lex->select_limit= 0;
1284
2394
 
1285
2395
  fake_select_lex->context.outer_context=first_sl->context.outer_context;
1286
 
  /* allow item list resolving in fake select for ORDER BY */
 
2396
  /* allow item list resolving in fake select for order_st BY */
1287
2397
  fake_select_lex->context.resolve_in_select_list= true;
1288
2398
  fake_select_lex->context.select_lex= fake_select_lex;
1289
2399
 
1291
2401
  {
1292
2402
    /*
1293
2403
      This works only for
1294
 
      (SELECT ... ORDER BY list [LIMIT n]) ORDER BY order_list [LIMIT m],
1295
 
      (SELECT ... LIMIT n) ORDER BY order_list [LIMIT m]
 
2404
      (SELECT ... order_st BY list [LIMIT n]) order_st BY order_list [LIMIT m],
 
2405
      (SELECT ... LIMIT n) order_st BY order_list [LIMIT m]
1296
2406
      just before the parser starts processing order_list
1297
2407
    */
1298
2408
    global_parameters= fake_select_lex;
1415
2525
 
1416
2526
 
1417
2527
/**
 
2528
  Reload/resets privileges and the different caches.
 
2529
 
 
2530
  @param session Thread handler (can be NULL!)
 
2531
  @param options What should be reset/reloaded (tables, privileges, slave...)
 
2532
  @param tables Tables to flush (if any)
 
2533
  @param write_to_binlog True if we can write to the binlog.
 
2534
 
 
2535
  @note Depending on 'options', it may be very bad to write the
 
2536
    query to the binlog (e.g. FLUSH SLAVE); this is a
 
2537
    pointer where reload_cache() will put 0 if
 
2538
    it thinks we really should not write to the binlog.
 
2539
    Otherwise it will put 1.
 
2540
 
 
2541
  @return Error status code
 
2542
    @retval 0 Ok
 
2543
    @retval !=0  Error; session->killed is set or session->is_error() is true
 
2544
*/
 
2545
 
 
2546
bool reload_cache(Session *session, ulong options, TableList *tables, bool *write_to_binlog)
 
2547
{
 
2548
  bool result=0;
 
2549
  select_errors=0;                              /* Write if more errors */
 
2550
  bool tmp_write_to_binlog= 1;
 
2551
 
 
2552
  if (options & REFRESH_LOG)
 
2553
  {
 
2554
    /*
 
2555
      Flush the normal query log, the update log, the binary log,
 
2556
      the slow query log, the relay log (if it exists) and the log
 
2557
      tables.
 
2558
    */
 
2559
 
 
2560
    /*
 
2561
      Writing this command to the binlog may result in infinite loops
 
2562
      when doing mysqlbinlog|mysql, and anyway it does not really make
 
2563
      sense to log it automatically (would cause more trouble to users
 
2564
      than it would help them)
 
2565
    */
 
2566
    tmp_write_to_binlog= 0;
 
2567
 
 
2568
    if (ha_flush_logs(NULL))
 
2569
      result=1;
 
2570
  }
 
2571
  /*
 
2572
    Note that if REFRESH_READ_LOCK bit is set then REFRESH_TABLES is set too
 
2573
    (see sql_yacc.yy)
 
2574
  */
 
2575
  if (options & (REFRESH_TABLES | REFRESH_READ_LOCK))
 
2576
  {
 
2577
    if ((options & REFRESH_READ_LOCK) && session)
 
2578
    {
 
2579
      /*
 
2580
        We must not try to aspire a global read lock if we have a write
 
2581
        locked table. This would lead to a deadlock when trying to
 
2582
        reopen (and re-lock) the table after the flush.
 
2583
      */
 
2584
      if (session->locked_tables)
 
2585
      {
 
2586
        THR_LOCK_DATA **lock_p= session->locked_tables->locks;
 
2587
        THR_LOCK_DATA **end_p= lock_p + session->locked_tables->lock_count;
 
2588
 
 
2589
        for (; lock_p < end_p; lock_p++)
 
2590
        {
 
2591
          if ((*lock_p)->type >= TL_WRITE_ALLOW_WRITE)
 
2592
          {
 
2593
            my_error(ER_LOCK_OR_ACTIVE_TRANSACTION, MYF(0));
 
2594
            return 1;
 
2595
          }
 
2596
        }
 
2597
      }
 
2598
      /*
 
2599
        Writing to the binlog could cause deadlocks, as we don't log
 
2600
        UNLOCK TABLES
 
2601
      */
 
2602
      tmp_write_to_binlog= 0;
 
2603
      if (lock_global_read_lock(session))
 
2604
        return 1;                               // Killed
 
2605
      result= close_cached_tables(session, tables, false, (options & REFRESH_FAST) ?
 
2606
                                  false : true, true);
 
2607
      if (make_global_read_lock_block_commit(session)) // Killed
 
2608
      {
 
2609
        /* Don't leave things in a half-locked state */
 
2610
        unlock_global_read_lock(session);
 
2611
        return 1;
 
2612
      }
 
2613
    }
 
2614
    else
 
2615
      result= close_cached_tables(session, tables, false, (options & REFRESH_FAST) ?
 
2616
                                  false : true, false);
 
2617
  }
 
2618
  if (session && (options & REFRESH_STATUS))
 
2619
    session->refresh_status();
 
2620
 *write_to_binlog= tmp_write_to_binlog;
 
2621
 
 
2622
 return result;
 
2623
}
 
2624
 
 
2625
 
 
2626
/**
 
2627
  kill on thread.
 
2628
 
 
2629
  @param session                        Thread class
 
2630
  @param id                     Thread id
 
2631
  @param only_kill_query        Should it kill the query or the connection
 
2632
 
 
2633
  @note
 
2634
    This is written such that we have a short lock on LOCK_thread_count
 
2635
*/
 
2636
 
 
2637
static unsigned int
 
2638
kill_one_thread(Session *, ulong id, bool only_kill_query)
 
2639
{
 
2640
  Session *tmp;
 
2641
  uint32_t error=ER_NO_SUCH_THREAD;
 
2642
  pthread_mutex_lock(&LOCK_thread_count); // For unlink from list
 
2643
  I_List_iterator<Session> it(session_list);
 
2644
  while ((tmp=it++))
 
2645
  {
 
2646
    if (tmp->thread_id == id)
 
2647
    {
 
2648
      pthread_mutex_lock(&tmp->LOCK_delete);    // Lock from delete
 
2649
      break;
 
2650
    }
 
2651
  }
 
2652
  pthread_mutex_unlock(&LOCK_thread_count);
 
2653
  if (tmp)
 
2654
  {
 
2655
    tmp->awake(only_kill_query ? Session::KILL_QUERY : Session::KILL_CONNECTION);
 
2656
    error=0;
 
2657
    pthread_mutex_unlock(&tmp->LOCK_delete);
 
2658
  }
 
2659
  return(error);
 
2660
}
 
2661
 
 
2662
 
 
2663
/*
 
2664
  kills a thread and sends response
 
2665
 
 
2666
  SYNOPSIS
 
2667
    sql_kill()
 
2668
    session                     Thread class
 
2669
    id                  Thread id
 
2670
    only_kill_query     Should it kill the query or the connection
 
2671
*/
 
2672
 
 
2673
void sql_kill(Session *session, ulong id, bool only_kill_query)
 
2674
{
 
2675
  uint32_t error;
 
2676
  if (!(error= kill_one_thread(session, id, only_kill_query)))
 
2677
    session->my_ok();
 
2678
  else
 
2679
    my_error(error, MYF(0), id);
 
2680
}
 
2681
 
 
2682
 
 
2683
/** If pointer is not a null pointer, append filename to it. */
 
2684
 
 
2685
bool append_file_to_dir(Session *session, const char **filename_ptr,
 
2686
                        const char *table_name)
 
2687
{
 
2688
  char buff[FN_REFLEN],*ptr, *end;
 
2689
  if (!*filename_ptr)
 
2690
    return 0;                                   // nothing to do
 
2691
 
 
2692
  /* Check that the filename is not too long and it's a hard path */
 
2693
  if (strlen(*filename_ptr)+strlen(table_name) >= FN_REFLEN-1 ||
 
2694
      !test_if_hard_path(*filename_ptr))
 
2695
  {
 
2696
    my_error(ER_WRONG_TABLE_NAME, MYF(0), *filename_ptr);
 
2697
    return 1;
 
2698
  }
 
2699
  /* Fix is using unix filename format on dos */
 
2700
  strcpy(buff,*filename_ptr);
 
2701
  end=convert_dirname(buff, *filename_ptr, NULL);
 
2702
  if (!(ptr= (char*) session->alloc((size_t) (end-buff) + strlen(table_name)+1)))
 
2703
    return 1;                                   // End of memory
 
2704
  *filename_ptr=ptr;
 
2705
  sprintf(ptr,"%s%s",buff,table_name);
 
2706
  return 0;
 
2707
}
 
2708
 
 
2709
 
 
2710
/**
1418
2711
  Check if the select is a simple select (not an union).
1419
2712
 
1420
2713
  @retval
1432
2725
    char command[80];
1433
2726
    Lex_input_stream *lip= session->m_lip;
1434
2727
    strncpy(command, lip->yylval->symbol.str,
1435
 
            min(lip->yylval->symbol.length, (uint32_t)(sizeof(command)-1)));
1436
 
    command[min(lip->yylval->symbol.length, (uint32_t)(sizeof(command)-1))]=0;
 
2728
            cmin(lip->yylval->symbol.length, sizeof(command)-1));
 
2729
    command[cmin(lip->yylval->symbol.length, sizeof(command)-1)]=0;
1437
2730
    my_error(ER_CANT_USE_OPTION_HERE, MYF(0), command);
1438
2731
    return 1;
1439
2732
  }
1511
2804
  return(false);
1512
2805
}
1513
2806
 
 
2807
/**
 
2808
  Multi delete query pre-check.
 
2809
 
 
2810
  @param session                        Thread handler
 
2811
  @param tables         Global/local table list
 
2812
 
 
2813
  @retval
 
2814
    false OK
 
2815
  @retval
 
2816
    true  error
 
2817
*/
 
2818
 
 
2819
bool multi_delete_precheck(Session *session, TableList *)
 
2820
{
 
2821
  Select_Lex *select_lex= &session->lex->select_lex;
 
2822
  TableList **save_query_tables_own_last= session->lex->query_tables_own_last;
 
2823
 
 
2824
  session->lex->query_tables_own_last= 0;
 
2825
  session->lex->query_tables_own_last= save_query_tables_own_last;
 
2826
 
 
2827
  if ((session->options & OPTION_SAFE_UPDATES) && !select_lex->where)
 
2828
  {
 
2829
    my_message(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE,
 
2830
               ER(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE), MYF(0));
 
2831
    return(true);
 
2832
  }
 
2833
  return(false);
 
2834
}
 
2835
 
 
2836
 
 
2837
/*
 
2838
  Given a table in the source list, find a correspondent table in the
 
2839
  table references list.
 
2840
 
 
2841
  @param lex Pointer to LEX representing multi-delete.
 
2842
  @param src Source table to match.
 
2843
  @param ref Table references list.
 
2844
 
 
2845
  @remark The source table list (tables listed before the FROM clause
 
2846
  or tables listed in the FROM clause before the USING clause) may
 
2847
  contain table names or aliases that must match unambiguously one,
 
2848
  and only one, table in the target table list (table references list,
 
2849
  after FROM/USING clause).
 
2850
 
 
2851
  @return Matching table, NULL otherwise.
 
2852
*/
 
2853
 
 
2854
static TableList *multi_delete_table_match(LEX *, TableList *tbl,
 
2855
                                           TableList *tables)
 
2856
{
 
2857
  TableList *match= NULL;
 
2858
 
 
2859
  for (TableList *elem= tables; elem; elem= elem->next_local)
 
2860
  {
 
2861
    int cmp;
 
2862
 
 
2863
    if (tbl->is_fqtn && elem->is_alias)
 
2864
      continue; /* no match */
 
2865
    if (tbl->is_fqtn && elem->is_fqtn)
 
2866
      cmp= my_strcasecmp(table_alias_charset, tbl->table_name, elem->table_name) ||
 
2867
           strcmp(tbl->db, elem->db);
 
2868
    else if (elem->is_alias)
 
2869
      cmp= my_strcasecmp(table_alias_charset, tbl->alias, elem->alias);
 
2870
    else
 
2871
      cmp= my_strcasecmp(table_alias_charset, tbl->table_name, elem->table_name) ||
 
2872
           strcmp(tbl->db, elem->db);
 
2873
 
 
2874
    if (cmp)
 
2875
      continue;
 
2876
 
 
2877
    if (match)
 
2878
    {
 
2879
      my_error(ER_NONUNIQ_TABLE, MYF(0), elem->alias);
 
2880
      return(NULL);
 
2881
    }
 
2882
 
 
2883
    match= elem;
 
2884
  }
 
2885
 
 
2886
  if (!match)
 
2887
    my_error(ER_UNKNOWN_TABLE, MYF(0), tbl->table_name, "MULTI DELETE");
 
2888
 
 
2889
  return(match);
 
2890
}
 
2891
 
 
2892
 
 
2893
/**
 
2894
  Link tables in auxilary table list of multi-delete with corresponding
 
2895
  elements in main table list, and set proper locks for them.
 
2896
 
 
2897
  @param lex   pointer to LEX representing multi-delete
 
2898
 
 
2899
  @retval
 
2900
    false   success
 
2901
  @retval
 
2902
    true    error
 
2903
*/
 
2904
 
 
2905
bool multi_delete_set_locks_and_link_aux_tables(LEX *lex)
 
2906
{
 
2907
  TableList *tables= (TableList*)lex->select_lex.table_list.first;
 
2908
  TableList *target_tbl;
 
2909
 
 
2910
  lex->table_count= 0;
 
2911
 
 
2912
  for (target_tbl= (TableList *)lex->auxiliary_table_list.first;
 
2913
       target_tbl; target_tbl= target_tbl->next_local)
 
2914
  {
 
2915
    lex->table_count++;
 
2916
    /* All tables in aux_tables must be found in FROM PART */
 
2917
    TableList *walk= multi_delete_table_match(lex, target_tbl, tables);
 
2918
    if (!walk)
 
2919
      return(true);
 
2920
    if (!walk->derived)
 
2921
    {
 
2922
      target_tbl->table_name= walk->table_name;
 
2923
      target_tbl->table_name_length= walk->table_name_length;
 
2924
    }
 
2925
    walk->updating= target_tbl->updating;
 
2926
    walk->lock_type= target_tbl->lock_type;
 
2927
    target_tbl->correspondent_table= walk;      // Remember corresponding table
 
2928
  }
 
2929
  return(false);
 
2930
}
 
2931
 
1514
2932
 
1515
2933
/**
1516
2934
  simple INSERT query pre-check.
1542
2960
 
1543
2961
 
1544
2962
/**
 
2963
  CREATE TABLE query pre-check.
 
2964
 
 
2965
  @param session                        Thread handler
 
2966
  @param tables         Global table list
 
2967
  @param create_table           Table which will be created
 
2968
 
 
2969
  @retval
 
2970
    false   OK
 
2971
  @retval
 
2972
    true   Error
 
2973
*/
 
2974
 
 
2975
bool create_table_precheck(Session *, TableList *,
 
2976
                           TableList *create_table)
 
2977
{
 
2978
  bool error= true;                                 // Error message is given
 
2979
 
 
2980
  if (create_table && (strcmp(create_table->db, "information_schema") == 0))
 
2981
  {
 
2982
    my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), "", "", INFORMATION_SCHEMA_NAME.c_str());
 
2983
    return(true);
 
2984
  }
 
2985
 
 
2986
  error= false;
 
2987
 
 
2988
  return(error);
 
2989
}
 
2990
 
 
2991
 
 
2992
/**
1545
2993
  negate given expression.
1546
2994
 
1547
2995
  @param session  thread handler
1650
3098
}
1651
3099
 
1652
3100
 
 
3101
/*
 
3102
  Check if path does not contain mysql data home directory
 
3103
  SYNOPSIS
 
3104
    test_if_data_home_dir()
 
3105
    dir                     directory
 
3106
    conv_home_dir           converted data home directory
 
3107
    home_dir_len            converted data home directory length
 
3108
 
 
3109
  RETURN VALUES
 
3110
    0   ok
 
3111
    1   error
 
3112
*/
 
3113
 
 
3114
bool test_if_data_home_dir(const char *dir)
 
3115
{
 
3116
  char path[FN_REFLEN], conv_path[FN_REFLEN];
 
3117
  uint32_t dir_len, home_dir_len= strlen(drizzle_unpacked_real_data_home);
 
3118
 
 
3119
  if (!dir)
 
3120
    return(0);
 
3121
 
 
3122
  (void) fn_format(path, dir, "", "",
 
3123
                   (MY_RETURN_REAL_PATH|MY_RESOLVE_SYMLINKS));
 
3124
  dir_len= unpack_dirname(conv_path, dir);
 
3125
 
 
3126
  if (home_dir_len < dir_len)
 
3127
  {
 
3128
    if (!my_strnncoll(character_set_filesystem,
 
3129
                      (const unsigned char*) conv_path, home_dir_len,
 
3130
                      (const unsigned char*) drizzle_unpacked_real_data_home,
 
3131
                      home_dir_len))
 
3132
      return(1);
 
3133
  }
 
3134
  return(0);
 
3135
}
 
3136
 
 
3137
 
 
3138
extern int DRIZZLEparse(void *session); // from sql_yacc.cc
 
3139
 
 
3140
 
1653
3141
/**
1654
3142
  This is a wrapper of DRIZZLEparse(). All the code should call parse_sql()
1655
3143
  instead of DRIZZLEparse().
1662
3150
    @retval true on parsing error.
1663
3151
*/
1664
3152
 
1665
 
static bool parse_sql(Session *session, Lex_input_stream *lip)
 
3153
bool parse_sql(Session *session, Lex_input_stream *lip)
1666
3154
{
1667
3155
  assert(session->m_lip == NULL);
1668
3156
 
1669
 
  DRIZZLE_QUERY_PARSE_START(session->getQueryString()->c_str());
1670
 
 
1671
3157
  /* Set Lex_input_stream. */
1672
3158
 
1673
3159
  session->m_lip= lip;
1684
3170
 
1685
3171
  session->m_lip= NULL;
1686
3172
 
1687
 
  DRIZZLE_QUERY_PARSE_DONE(mysql_parse_status || session->is_fatal_error);
1688
 
 
1689
3173
  /* That's it. */
1690
3174
 
1691
3175
  return mysql_parse_status || session->is_fatal_error;
1694
3178
/**
1695
3179
  @} (end of group Runtime_Environment)
1696
3180
*/
1697
 
 
1698
 
} /* namespace drizzled */