~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_parse.cc

Monty fixes pluss a few from me for charset.

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 <mysys/hash.h>
 
19
#include <drizzled/logging.h>
 
20
#include <drizzled/db.h>
21
21
#include <drizzled/error.h>
22
22
#include <drizzled/nested_join.h>
23
23
#include <drizzled/query_id.h>
24
 
#include "drizzled/transaction_services.h"
25
24
#include <drizzled/sql_parse.h>
26
25
#include <drizzled/data_home.h>
27
26
#include <drizzled/sql_base.h>
28
27
#include <drizzled/show.h>
29
 
#include <drizzled/db.h>
 
28
#include <drizzled/info_schema.h>
 
29
#include <drizzled/rename.h>
30
30
#include <drizzled/function/time/unix_timestamp.h>
31
31
#include <drizzled/function/get_system_var.h>
32
32
#include <drizzled/item/cmpfunc.h>
33
33
#include <drizzled/item/null.h>
34
34
#include <drizzled/session.h>
35
35
#include <drizzled/sql_load.h>
 
36
#include <drizzled/connect.h>
36
37
#include <drizzled/lock.h>
37
38
#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>
 
39
#include <drizzled/command.h>
54
40
 
55
41
#include <bitset>
56
42
#include <algorithm>
57
 
#include <boost/date_time.hpp>
58
 
#include "drizzled/internal/my_sys.h"
59
43
 
60
44
using namespace std;
61
45
 
62
 
extern int DRIZZLEparse(void *session); // from sql_yacc.cc
63
 
 
64
 
namespace drizzled
65
 
{
66
 
 
67
46
/* Prototypes */
 
47
static bool append_file_to_dir(Session *session, const char **filename_ptr,
 
48
                               const char *table_name);
 
49
 
68
50
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
51
 
72
52
/**
73
53
  @defgroup Runtime_Environment Runtime Environment
76
56
 
77
57
extern size_t my_thread_stack_size;
78
58
extern const CHARSET_INFO *character_set_filesystem;
 
59
const char *any_db="*any*";     // Special symbol for check_access
79
60
 
80
61
const LEX_STRING command_name[COM_END+1]={
81
62
  { C_STRING_WITH_LEN("Sleep") },
125
106
  sql_command_flags[SQLCOM_DROP_INDEX]=     CF_CHANGES_DATA;
126
107
 
127
108
  sql_command_flags[SQLCOM_UPDATE]=         CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
 
109
  sql_command_flags[SQLCOM_UPDATE_MULTI]=   CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
128
110
  sql_command_flags[SQLCOM_INSERT]=         CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
129
111
  sql_command_flags[SQLCOM_INSERT_SELECT]=  CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
130
112
  sql_command_flags[SQLCOM_DELETE]=         CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
 
113
  sql_command_flags[SQLCOM_DELETE_MULTI]=   CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
131
114
  sql_command_flags[SQLCOM_REPLACE]=        CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
132
115
  sql_command_flags[SQLCOM_REPLACE_SELECT]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
133
116
 
 
117
  sql_command_flags[SQLCOM_SHOW_STATUS]=      CF_STATUS_COMMAND;
 
118
  sql_command_flags[SQLCOM_SHOW_DATABASES]=   CF_STATUS_COMMAND;
 
119
  sql_command_flags[SQLCOM_SHOW_OPEN_TABLES]= CF_STATUS_COMMAND;
 
120
  sql_command_flags[SQLCOM_SHOW_FIELDS]=      CF_STATUS_COMMAND;
 
121
  sql_command_flags[SQLCOM_SHOW_KEYS]=        CF_STATUS_COMMAND;
 
122
  sql_command_flags[SQLCOM_SHOW_VARIABLES]=   CF_STATUS_COMMAND;
134
123
  sql_command_flags[SQLCOM_SHOW_WARNS]= CF_STATUS_COMMAND;
135
124
  sql_command_flags[SQLCOM_SHOW_ERRORS]= CF_STATUS_COMMAND;
 
125
  sql_command_flags[SQLCOM_SHOW_ENGINE_STATUS]= CF_STATUS_COMMAND;
 
126
  sql_command_flags[SQLCOM_SHOW_PROCESSLIST]= CF_STATUS_COMMAND;
136
127
  sql_command_flags[SQLCOM_SHOW_CREATE_DB]=  CF_STATUS_COMMAND;
137
128
  sql_command_flags[SQLCOM_SHOW_CREATE]=  CF_STATUS_COMMAND;
138
129
 
 
130
   sql_command_flags[SQLCOM_SHOW_TABLES]=       (CF_STATUS_COMMAND |
 
131
                                               CF_SHOW_TABLE_COMMAND);
 
132
  sql_command_flags[SQLCOM_SHOW_TABLE_STATUS]= (CF_STATUS_COMMAND |
 
133
                                                CF_SHOW_TABLE_COMMAND);
139
134
  /*
140
135
    The following admin table operations are allowed
141
136
    on log tables.
142
137
  */
 
138
  sql_command_flags[SQLCOM_OPTIMIZE]=         CF_WRITE_LOGS_COMMAND;
143
139
  sql_command_flags[SQLCOM_ANALYZE]=          CF_WRITE_LOGS_COMMAND;
144
140
}
145
141
 
 
142
 
 
143
bool is_update_query(enum enum_sql_command command)
 
144
{
 
145
  assert(command >= 0 && command <= SQLCOM_END);
 
146
  return (sql_command_flags[command].test(CF_BIT_CHANGES_DATA));
 
147
}
 
148
 
146
149
/**
147
150
  Perform one connection-level (COM_XXXX) command.
148
151
 
170
173
  bool error= 0;
171
174
  Query_id &query_id= Query_id::get_query_id();
172
175
 
173
 
  DRIZZLE_COMMAND_START(session->thread_id, command);
174
 
 
175
 
  session->command= command;
 
176
  session->command=command;
176
177
  session->lex->sql_command= SQLCOM_END; /* to avoid confusing VIEW detectors */
177
178
  session->set_time();
178
 
  session->setQueryId(query_id.value());
 
179
  session->query_id= query_id.value();
179
180
 
180
181
  switch( command ) {
181
182
  /* Ignore these statements. */
183
184
    break;
184
185
  /* Increase id and count all other statements. */
185
186
  default:
186
 
    session->status_var.questions++;
 
187
    statistic_increment(session->status_var.questions, &LOCK_status);
187
188
    query_id.next();
188
189
  }
189
190
 
190
191
  /* TODO: set session->lex->sql_command to SQLCOM_END here */
191
192
 
192
 
  plugin::Logging::preDo(session);
193
 
  if (unlikely(plugin::EventObserver::beforeStatement(*session)))
194
 
  {
195
 
    // We should do something about an error...
196
 
  }
 
193
  logging_pre_do(session);
197
194
 
198
195
  session->server_status&=
199
196
           ~(SERVER_QUERY_NO_INDEX_USED | SERVER_QUERY_NO_GOOD_INDEX_USED);
200
197
  switch (command) {
201
198
  case COM_INIT_DB:
202
199
  {
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))
 
200
    LEX_STRING tmp;
 
201
    status_var_increment(session->status_var.com_stat[SQLCOM_CHANGE_DB]);
 
202
    tmp.str= packet;
 
203
    tmp.length= packet_length;
 
204
    if (!mysql_change_db(session, &tmp, false))
214
205
    {
215
206
      session->my_ok();
216
207
    }
218
209
  }
219
210
  case COM_QUERY:
220
211
  {
221
 
    if (not session->readAndStoreQuery(packet, packet_length))
 
212
    if (! session->readAndStoreQuery(packet, packet_length))
222
213
      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()));
 
214
    const char* end_of_stmt= NULL;
226
215
 
227
 
    mysql_parse(session, session->getQueryString()->c_str(), session->getQueryString()->length());
 
216
    mysql_parse(session, session->query, session->query_length, &end_of_stmt);
228
217
 
229
218
    break;
230
219
  }
231
220
  case COM_QUIT:
232
221
    /* We don't calculate statistics for this command */
 
222
    session->protocol->setError(0);
233
223
    session->main_da.disable_status();              // Don't send anything back
234
224
    error=true;                                 // End server
235
225
    break;
236
226
  case COM_SHUTDOWN:
237
227
  {
238
 
    session->status_var.com_other++;
 
228
    status_var_increment(session->status_var.com_other);
239
229
    session->my_eof();
240
230
    session->close_thread_tables();                     // Free before kill
241
231
    kill_drizzle();
243
233
    break;
244
234
  }
245
235
  case COM_PING:
246
 
    session->status_var.com_other++;
 
236
    status_var_increment(session->status_var.com_other);
247
237
    session->my_ok();                           // Tell client we are alive
248
238
    break;
249
239
  case COM_SLEEP:
256
246
 
257
247
  /* If commit fails, we should be able to reset the OK status. */
258
248
  session->main_da.can_overwrite_status= true;
259
 
  TransactionServices &transaction_services= TransactionServices::singleton();
260
 
  transaction_services.autocommitOrRollback(session, session->is_error());
 
249
  ha_autocommit_or_rollback(session, session->is_error());
261
250
  session->main_da.can_overwrite_status= false;
262
251
 
263
252
  session->transaction.stmt.reset();
269
258
    if (! session->main_da.is_set())
270
259
      session->send_kill_message();
271
260
  }
272
 
  if (session->getKilled() == Session::KILL_QUERY || session->getKilled() == Session::KILL_BAD_DATA)
 
261
  if (session->killed == Session::KILL_QUERY || session->killed == Session::KILL_BAD_DATA)
273
262
  {
274
 
    session->setKilled(Session::NOT_KILLED);
275
 
    session->setAbort(false);
 
263
    session->killed= Session::NOT_KILLED;
 
264
    session->mysys_var->abort= 0;
276
265
  }
277
266
 
278
267
  /* Can not be true, but do not take chances in production. */
282
271
  {
283
272
  case Diagnostics_area::DA_ERROR:
284
273
    /* The query failed, send error to log and abort bootstrap. */
285
 
    session->client->sendError(session->main_da.sql_errno(),
286
 
                               session->main_da.message());
 
274
    session->protocol->sendError(session->main_da.sql_errno(),
 
275
                                 session->main_da.message());
287
276
    break;
288
277
 
289
278
  case Diagnostics_area::DA_EOF:
290
 
    session->client->sendEOF();
 
279
    session->protocol->sendEOF();
291
280
    break;
292
281
 
293
282
  case Diagnostics_area::DA_OK:
294
 
    session->client->sendOK();
 
283
    session->protocol->sendOK();
295
284
    break;
296
285
 
297
286
  case Diagnostics_area::DA_DISABLED:
299
288
 
300
289
  case Diagnostics_area::DA_EMPTY:
301
290
  default:
302
 
    session->client->sendOK();
 
291
    session->protocol->sendOK();
303
292
    break;
304
293
  }
305
294
 
309
298
  /* Free tables */
310
299
  session->close_thread_tables();
311
300
 
312
 
  plugin::Logging::postDo(session);
313
 
  if (unlikely(plugin::EventObserver::afterStatement(*session)))
314
 
  {
315
 
    // We should do something about an error...
316
 
  }
 
301
  logging_post_do(session);
317
302
 
318
303
  /* Store temp state for processlist */
319
304
  session->set_proc_info("cleaning up");
320
 
  session->command= COM_SLEEP;
321
 
  session->resetQueryString();
 
305
  session->command=COM_SLEEP;
 
306
  memset(session->process_list_info, 0, PROCESS_LIST_WIDTH);
 
307
  session->query=0;
 
308
  session->query_length=0;
322
309
 
323
310
  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;
 
311
  session->packet.shrink(session->variables.net_buffer_length); // Reclaim some memory
 
312
  free_root(session->mem_root,MYF(MY_KEEP_PREALLOC));
 
313
  return(error);
336
314
}
337
315
 
338
316
 
361
339
    1                 out of memory or SHOW commands are not allowed
362
340
                      in this version of the server.
363
341
*/
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)
 
342
 
 
343
int prepare_schema_table(Session *session, LEX *lex, Table_ident *table_ident,
 
344
                         const string& schema_table_name)
386
345
{
387
346
  Select_Lex *schema_select_lex= NULL;
388
347
 
 
348
 
 
349
  if (schema_table_name.compare("TABLES") == 0 ||
 
350
      schema_table_name.compare("TABLE_NAMES") == 0)
 
351
  {
 
352
    LEX_STRING db;
 
353
    size_t dummy;
 
354
    if (lex->select_lex.db == NULL &&
 
355
        lex->copy_db_to(&lex->select_lex.db, &dummy))
 
356
    {
 
357
      return (1);
 
358
    }
 
359
    schema_select_lex= new Select_Lex();
 
360
    db.str= schema_select_lex->db= lex->select_lex.db;
 
361
    schema_select_lex->table_list.first= NULL;
 
362
    db.length= strlen(db.str);
 
363
 
 
364
    if (check_db_name(&db))
 
365
    {
 
366
      my_error(ER_WRONG_DB_NAME, MYF(0), db.str);
 
367
      return (1);
 
368
    }
 
369
  }
 
370
  else if (schema_table_name.compare("COLUMNS") == 0 ||
 
371
           schema_table_name.compare("STATISTICS") == 0)
 
372
  {
 
373
    assert(table_ident);
 
374
    TableList **query_tables_last= lex->query_tables_last;
 
375
    schema_select_lex= new Select_Lex();
 
376
    /* 'parent_lex' is used in init_query() so it must be before it. */
 
377
    schema_select_lex->parent_lex= lex;
 
378
    schema_select_lex->init_query();
 
379
    if (! schema_select_lex->add_table_to_list(session, table_ident, 0, 0, TL_READ))
 
380
    {
 
381
      return (1);
 
382
    }
 
383
    lex->query_tables_last= query_tables_last;
 
384
  }
 
385
 
389
386
  Select_Lex *select_lex= lex->current_select;
390
387
  assert(select_lex);
391
 
  if (_schema_select(session, select_lex, schema_table_name))
 
388
  if (make_schema_select(session, select_lex, schema_table_name))
392
389
  {
393
390
    return(1);
394
391
  }
429
426
    true        Error
430
427
*/
431
428
 
432
 
static int mysql_execute_command(Session *session)
 
429
static int
 
430
mysql_execute_command(Session *session)
433
431
{
434
 
  bool res= false;
 
432
  int res= false;
 
433
  bool comm_not_executed= false;
 
434
  bool need_start_waiting= false; // have protection against global read lock
435
435
  LEX  *lex= session->lex;
436
436
  /* first Select_Lex (have special meaning for many of non-SELECTcommands) */
437
437
  Select_Lex *select_lex= &lex->select_lex;
 
438
  /* first table of first Select_Lex */
 
439
  TableList *first_table= (TableList*) select_lex->table_list.first;
438
440
  /* list of all tables in query */
439
441
  TableList *all_tables;
 
442
  /* most outer Select_Lex_Unit of query */
 
443
  Select_Lex_Unit *unit= &lex->unit;
 
444
  /* A peek into the query string */
 
445
  size_t proc_info_len= session->query_length > PROCESS_LIST_WIDTH ?
 
446
                        PROCESS_LIST_WIDTH : session->query_length;
 
447
 
 
448
  memcpy(session->process_list_info, session->query, proc_info_len);
 
449
  session->process_list_info[proc_info_len]= '\0';
440
450
 
441
451
  /*
442
452
    In many cases first table of main Select_Lex have special meaning =>
468
478
    variables, but for now this is probably good enough.
469
479
    Don't reset warnings when executing a stored routine.
470
480
  */
471
 
  if (all_tables || ! lex->is_single_level_stmt())
472
 
  {
 
481
  if (all_tables || !lex->is_single_level_stmt())
473
482
    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();
 
483
 
 
484
  status_var_increment(session->status_var.com_stat[lex->sql_command]);
 
485
 
 
486
  assert(session->transaction.stmt.modified_non_trans_table == false);
 
487
 
 
488
 
 
489
  switch (lex->sql_command) {
 
490
  case SQLCOM_EMPTY_QUERY:
 
491
    session->my_ok();
 
492
    break;
 
493
 
 
494
  case SQLCOM_SHOW_WARNS:
 
495
  {
 
496
    res= mysqld_show_warnings(session, (uint32_t)
 
497
                              ((1L << (uint32_t) DRIZZLE_ERROR::WARN_LEVEL_NOTE) |
 
498
                               (1L << (uint32_t) DRIZZLE_ERROR::WARN_LEVEL_WARN) |
 
499
                               (1L << (uint32_t) DRIZZLE_ERROR::WARN_LEVEL_ERROR)
 
500
                               ));
 
501
    break;
 
502
  }
 
503
  case SQLCOM_SHOW_ERRORS:
 
504
  {
 
505
    res= mysqld_show_warnings(session, (uint32_t)
 
506
                              (1L << (uint32_t) DRIZZLE_ERROR::WARN_LEVEL_ERROR));
 
507
    break;
 
508
  }
 
509
  case SQLCOM_ASSIGN_TO_KEYCACHE:
 
510
  {
 
511
    assert(first_table == all_tables && first_table != 0);
 
512
    res= mysql_assign_to_keycache(session, first_table, &lex->ident);
 
513
    break;
 
514
  }
 
515
  case SQLCOM_SHOW_ENGINE_STATUS:
 
516
    {
 
517
      res = ha_show_status(session, lex->show_engine, HA_ENGINE_STATUS);
 
518
      break;
 
519
    }
 
520
  case SQLCOM_CREATE_TABLE:
 
521
  {
 
522
    /* If CREATE TABLE of non-temporary table, do implicit commit */
 
523
    if (!(lex->create_info.options & HA_LEX_CREATE_TMP_TABLE))
 
524
    {
 
525
      if (! session->endActiveTransaction())
 
526
      {
 
527
        res= -1;
 
528
        break;
 
529
      }
 
530
    }
 
531
    assert(first_table == all_tables && first_table != 0);
 
532
    bool link_to_local;
 
533
    // Skip first table, which is the table we are creating
 
534
    TableList *create_table= lex->unlink_first_table(&link_to_local);
 
535
    TableList *select_tables= lex->query_tables;
 
536
    /*
 
537
      Code below (especially in mysql_create_table() and select_create
 
538
      methods) may modify HA_CREATE_INFO structure in LEX, so we have to
 
539
      use a copy of this structure to make execution prepared statement-
 
540
      safe. A shallow copy is enough as this code won't modify any memory
 
541
      referenced from this structure.
 
542
    */
 
543
    HA_CREATE_INFO create_info(lex->create_info);
 
544
    /*
 
545
      We need to copy alter_info for the same reasons of re-execution
 
546
      safety, only in case of Alter_info we have to do (almost) a deep
 
547
      copy.
 
548
    */
 
549
    Alter_info alter_info(lex->alter_info, session->mem_root);
 
550
 
 
551
    if (session->is_fatal_error)
 
552
    {
 
553
      /* If out of memory when creating a copy of alter_info. */
 
554
      res= 1;
 
555
      goto end_with_restore_list;
 
556
    }
 
557
 
 
558
    if ((res= create_table_precheck(session, select_tables, create_table)))
 
559
      goto end_with_restore_list;
 
560
 
 
561
    /* Might have been updated in create_table_precheck */
 
562
    create_info.alias= create_table->alias;
 
563
 
 
564
#ifdef HAVE_READLINK
 
565
    /* Fix names if symlinked tables */
 
566
    if (append_file_to_dir(session, &create_info.data_file_name,
 
567
                           create_table->table_name) ||
 
568
        append_file_to_dir(session, &create_info.index_file_name,
 
569
                           create_table->table_name))
 
570
      goto end_with_restore_list;
 
571
#endif
 
572
    /*
 
573
      The create-select command will open and read-lock the select table
 
574
      and then create, open and write-lock the new table. If a global
 
575
      read lock steps in, we get a deadlock. The write lock waits for
 
576
      the global read lock, while the global read lock waits for the
 
577
      select table to be closed. So we wait until the global readlock is
 
578
      gone before starting both steps. Note that
 
579
      wait_if_global_read_lock() sets a protection against a new global
 
580
      read lock when it succeeds. This needs to be released by
 
581
      start_waiting_global_read_lock(). We protect the normal CREATE
 
582
      TABLE in the same way. That way we avoid that a new table is
 
583
      created during a gobal read lock.
 
584
    */
 
585
    if (!(need_start_waiting= !wait_if_global_read_lock(session, 0, 1)))
 
586
    {
 
587
      res= 1;
 
588
      goto end_with_restore_list;
 
589
    }
 
590
    if (select_lex->item_list.elements)         // With select
 
591
    {
 
592
      select_result *result;
 
593
 
 
594
      select_lex->options|= SELECT_NO_UNLOCK;
 
595
      unit->set_limit(select_lex);
 
596
 
 
597
      if (!(create_info.options & HA_LEX_CREATE_TMP_TABLE))
 
598
      {
 
599
        lex->link_first_table_back(create_table, link_to_local);
 
600
        create_table->create= true;
 
601
      }
 
602
 
 
603
      if (!(res= session->open_and_lock_tables(lex->query_tables)))
 
604
      {
 
605
        /*
 
606
          Is table which we are changing used somewhere in other parts
 
607
          of query
 
608
        */
 
609
        if (!(create_info.options & HA_LEX_CREATE_TMP_TABLE))
 
610
        {
 
611
          TableList *duplicate;
 
612
          create_table= lex->unlink_first_table(&link_to_local);
 
613
          if ((duplicate= unique_table(session, create_table, select_tables, 0)))
 
614
          {
 
615
            my_error(ER_UPDATE_TABLE_USED, MYF(0), create_table->alias);
 
616
            res= 1;
 
617
            goto end_with_restore_list;
 
618
          }
 
619
        }
 
620
 
 
621
        /*
 
622
          select_create is currently not re-execution friendly and
 
623
          needs to be created for every execution of a PS/SP.
 
624
        */
 
625
        if ((result= new select_create(create_table,
 
626
                                       &create_info,
 
627
                                       lex->create_table_proto,
 
628
                                       &alter_info,
 
629
                                       select_lex->item_list,
 
630
                                       lex->duplicates,
 
631
                                       lex->ignore,
 
632
                                       select_tables)))
 
633
        {
 
634
          /*
 
635
            CREATE from SELECT give its Select_Lex for SELECT,
 
636
            and item_list belong to SELECT
 
637
          */
 
638
          res= handle_select(session, lex, result, 0);
 
639
          delete result;
 
640
        }
 
641
      }
 
642
      else if (!(create_info.options & HA_LEX_CREATE_TMP_TABLE))
 
643
        create_table= lex->unlink_first_table(&link_to_local);
 
644
 
 
645
    }
 
646
    else
 
647
    {
 
648
      /* So that CREATE TEMPORARY TABLE gets to binlog at commit/rollback */
 
649
      if (create_info.options & HA_LEX_CREATE_TMP_TABLE)
 
650
        session->options|= OPTION_KEEP_LOG;
 
651
      /* regular create */
 
652
      if (create_info.options & HA_LEX_CREATE_TABLE_LIKE)
 
653
        res= mysql_create_like_table(session, create_table, select_tables,
 
654
                                     &create_info);
 
655
      else
 
656
      {
 
657
        res= mysql_create_table(session, create_table->db,
 
658
                                create_table->table_name, &create_info,
 
659
                                lex->create_table_proto,
 
660
                                &alter_info, 0, 0);
 
661
      }
 
662
      if (!res)
 
663
        session->my_ok();
 
664
    }
 
665
 
 
666
    /* put tables back for PS rexecuting */
 
667
end_with_restore_list:
 
668
    lex->link_first_table_back(create_table, link_to_local);
 
669
    break;
 
670
  }
 
671
  case SQLCOM_CREATE_INDEX:
 
672
    /* Fall through */
 
673
  case SQLCOM_DROP_INDEX:
 
674
  /*
 
675
    CREATE INDEX and DROP INDEX are implemented by calling ALTER
 
676
    TABLE with proper arguments.
 
677
 
 
678
    In the future ALTER TABLE will notice that the request is to
 
679
    only add indexes and create these one by one for the existing
 
680
    table without having to do a full rebuild.
 
681
  */
 
682
  {
 
683
    /* Prepare stack copies to be re-execution safe */
 
684
    HA_CREATE_INFO create_info;
 
685
    Alter_info alter_info(lex->alter_info, session->mem_root);
 
686
 
 
687
    if (session->is_fatal_error) /* out of memory creating a copy of alter_info */
 
688
      goto error;
 
689
 
 
690
    assert(first_table == all_tables && first_table != 0);
 
691
    if (! session->endActiveTransaction())
 
692
      goto error;
 
693
 
 
694
    memset(&create_info, 0, sizeof(create_info));
 
695
    create_info.db_type= 0;
 
696
    create_info.row_type= ROW_TYPE_NOT_USED;
 
697
    create_info.default_table_charset= get_default_db_collation(session->db);
 
698
 
 
699
    res= mysql_alter_table(session, first_table->db, first_table->table_name,
 
700
                           &create_info, first_table, &alter_info,
 
701
                           0, (order_st*) 0, 0);
 
702
    break;
 
703
  }
 
704
  case SQLCOM_ALTER_TABLE:
 
705
    assert(first_table == all_tables && first_table != 0);
 
706
    {
 
707
      /*
 
708
        Code in mysql_alter_table() may modify its HA_CREATE_INFO argument,
 
709
        so we have to use a copy of this structure to make execution
 
710
        prepared statement- safe. A shallow copy is enough as no memory
 
711
        referenced from this structure will be modified.
 
712
      */
 
713
      HA_CREATE_INFO create_info(lex->create_info);
 
714
      Alter_info alter_info(lex->alter_info, session->mem_root);
 
715
 
 
716
      if (session->is_fatal_error) /* out of memory creating a copy of alter_info */
 
717
      {
 
718
        goto error;
 
719
      }
 
720
 
 
721
      /* Must be set in the parser */
 
722
      assert(select_lex->db);
 
723
 
 
724
      { // Rename of table
 
725
          TableList tmp_table;
 
726
          memset(&tmp_table, 0, sizeof(tmp_table));
 
727
          tmp_table.table_name= lex->name.str;
 
728
          tmp_table.db=select_lex->db;
 
729
      }
 
730
 
 
731
      /* Don't yet allow changing of symlinks with ALTER TABLE */
 
732
      if (create_info.data_file_name)
 
733
        push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN, 0,
 
734
                     "DATA DIRECTORY option ignored");
 
735
      if (create_info.index_file_name)
 
736
        push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN, 0,
 
737
                     "INDEX DIRECTORY option ignored");
 
738
      create_info.data_file_name= create_info.index_file_name= NULL;
 
739
      /* ALTER TABLE ends previous transaction */
 
740
      if (! session->endActiveTransaction())
 
741
        goto error;
 
742
 
 
743
      if (!(need_start_waiting= !wait_if_global_read_lock(session, 0, 1)))
 
744
      {
 
745
        res= 1;
 
746
        break;
 
747
      }
 
748
 
 
749
      res= mysql_alter_table(session, select_lex->db, lex->name.str,
 
750
                             &create_info,
 
751
                             first_table,
 
752
                             &alter_info,
 
753
                             select_lex->order_list.elements,
 
754
                             (order_st *) select_lex->order_list.first,
 
755
                             lex->ignore);
 
756
      break;
 
757
    }
 
758
  case SQLCOM_RENAME_TABLE:
 
759
  {
 
760
    assert(first_table == all_tables && first_table != 0);
 
761
    TableList *table;
 
762
    for (table= first_table; table; table= table->next_local->next_local)
 
763
    {
 
764
      TableList old_list, new_list;
 
765
      /*
 
766
        we do not need initialize old_list and new_list because we will
 
767
        come table[0] and table->next[0] there
 
768
      */
 
769
      old_list= table[0];
 
770
      new_list= table->next_local[0];
 
771
    }
 
772
 
 
773
    if (! session->endActiveTransaction() || drizzle_rename_tables(session, first_table))
 
774
    {
 
775
      goto error;
 
776
    }
 
777
    break;
 
778
  }
 
779
  case SQLCOM_SHOW_CREATE:
 
780
    assert(first_table == all_tables && first_table != 0);
 
781
    {
 
782
      res= drizzled_show_create(session, first_table);
 
783
      break;
 
784
    }
 
785
  case SQLCOM_CHECKSUM:
 
786
  {
 
787
    assert(first_table == all_tables && first_table != 0);
 
788
    res = mysql_checksum_table(session, first_table, &lex->check_opt);
 
789
    break;
 
790
  }
 
791
  case SQLCOM_CHECK:
 
792
  {
 
793
    assert(first_table == all_tables && first_table != 0);
 
794
    res = mysql_check_table(session, first_table, &lex->check_opt);
 
795
    select_lex->table_list.first= (unsigned char*) first_table;
 
796
    lex->query_tables=all_tables;
 
797
    break;
 
798
  }
 
799
  case SQLCOM_ANALYZE:
 
800
  {
 
801
    assert(first_table == all_tables && first_table != 0);
 
802
    res= mysql_analyze_table(session, first_table, &lex->check_opt);
 
803
    /* ! we write after unlocking the table */
 
804
    write_bin_log(session, true, session->query, session->query_length);
 
805
    select_lex->table_list.first= (unsigned char*) first_table;
 
806
    lex->query_tables=all_tables;
 
807
    break;
 
808
  }
 
809
 
 
810
  case SQLCOM_OPTIMIZE:
 
811
  {
 
812
    assert(first_table == all_tables && first_table != 0);
 
813
    res= mysql_optimize_table(session, first_table, &lex->check_opt);
 
814
    /* ! we write after unlocking the table */
 
815
    write_bin_log(session, true, session->query, session->query_length);
 
816
    select_lex->table_list.first= (unsigned char*) first_table;
 
817
    lex->query_tables=all_tables;
 
818
    break;
 
819
  }
 
820
  case SQLCOM_UPDATE:
 
821
    assert(first_table == all_tables && first_table != 0);
 
822
    if ((res= update_precheck(session, all_tables)))
 
823
      break;
 
824
    assert(select_lex->offset_limit == 0);
 
825
    unit->set_limit(select_lex);
 
826
    res= mysql_update(session, all_tables,
 
827
                      select_lex->item_list,
 
828
                      lex->value_list,
 
829
                      select_lex->where,
 
830
                      select_lex->order_list.elements,
 
831
                      (order_st *) select_lex->order_list.first,
 
832
                      unit->select_limit_cnt,
 
833
                      lex->duplicates, lex->ignore);
 
834
    break;
 
835
  case SQLCOM_UPDATE_MULTI:
 
836
  {
 
837
    assert(first_table == all_tables && first_table != 0);
 
838
    if ((res= update_precheck(session, all_tables)))
 
839
      break;
 
840
 
 
841
    if ((res= mysql_multi_update_prepare(session)))
 
842
      break;
 
843
 
 
844
    res= mysql_multi_update(session, all_tables,
 
845
                            &select_lex->item_list,
 
846
                            &lex->value_list,
 
847
                            select_lex->where,
 
848
                            select_lex->options,
 
849
                            lex->duplicates, lex->ignore, unit, select_lex);
 
850
    break;
 
851
  }
 
852
  case SQLCOM_REPLACE:
 
853
  case SQLCOM_INSERT:
 
854
  {
 
855
    assert(first_table == all_tables && first_table != 0);
 
856
    if ((res= insert_precheck(session, all_tables)))
 
857
      break;
 
858
 
 
859
    if (!(need_start_waiting= !wait_if_global_read_lock(session, 0, 1)))
 
860
    {
 
861
      res= 1;
 
862
      break;
 
863
    }
 
864
 
 
865
    res= mysql_insert(session, all_tables, lex->field_list, lex->many_values,
 
866
                      lex->update_list, lex->value_list,
 
867
                      lex->duplicates, lex->ignore);
 
868
 
 
869
    break;
 
870
  }
 
871
  case SQLCOM_REPLACE_SELECT:
 
872
  case SQLCOM_INSERT_SELECT:
 
873
  {
 
874
    select_result *sel_result;
 
875
    assert(first_table == all_tables && first_table != 0);
 
876
    if ((res= insert_precheck(session, all_tables)))
 
877
      break;
 
878
 
 
879
    /* Don't unlock tables until command is written to binary log */
 
880
    select_lex->options|= SELECT_NO_UNLOCK;
 
881
 
 
882
    unit->set_limit(select_lex);
 
883
 
 
884
    if (! (need_start_waiting= ! wait_if_global_read_lock(session, 0, 1)))
 
885
    {
 
886
      res= 1;
 
887
      break;
 
888
    }
 
889
 
 
890
    if (!(res= session->open_and_lock_tables(all_tables)))
 
891
    {
 
892
      /* Skip first table, which is the table we are inserting in */
 
893
      TableList *second_table= first_table->next_local;
 
894
      select_lex->table_list.first= (unsigned char*) second_table;
 
895
      select_lex->context.table_list=
 
896
        select_lex->context.first_name_resolution_table= second_table;
 
897
      res= mysql_insert_select_prepare(session);
 
898
      if (!res && (sel_result= new select_insert(first_table,
 
899
                                                 first_table->table,
 
900
                                                 &lex->field_list,
 
901
                                                 &lex->update_list,
 
902
                                                 &lex->value_list,
 
903
                                                 lex->duplicates,
 
904
                                                 lex->ignore)))
 
905
      {
 
906
        res= handle_select(session, lex, sel_result, OPTION_SETUP_TABLES_DONE);
 
907
        /*
 
908
          Invalidate the table in the query cache if something changed
 
909
          after unlocking when changes become visible.
 
910
          TODO: this is workaround. right way will be move invalidating in
 
911
          the unlock procedure.
 
912
        */
 
913
        if (first_table->lock_type ==  TL_WRITE_CONCURRENT_INSERT &&
 
914
            session->lock)
 
915
        {
 
916
          /* INSERT ... SELECT should invalidate only the very first table */
 
917
          TableList *save_table= first_table->next_local;
 
918
          first_table->next_local= 0;
 
919
          first_table->next_local= save_table;
 
920
        }
 
921
        delete sel_result;
 
922
      }
 
923
      /* revert changes for SP */
 
924
      select_lex->table_list.first= (unsigned char*) first_table;
 
925
    }
 
926
 
 
927
    break;
 
928
  }
 
929
  case SQLCOM_TRUNCATE:
 
930
    if (! session->endActiveTransaction())
 
931
    {
 
932
      res= -1;
 
933
      break;
 
934
    }
 
935
    assert(first_table == all_tables && first_table != 0);
 
936
    /*
 
937
      Don't allow this within a transaction because we want to use
 
938
      re-generate table
 
939
    */
 
940
    if (session->inTransaction())
 
941
    {
 
942
      my_message(ER_LOCK_OR_ACTIVE_TRANSACTION, ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
 
943
      goto error;
 
944
    }
 
945
 
 
946
    res= mysql_truncate(session, first_table, 0);
 
947
 
 
948
    break;
 
949
  case SQLCOM_DELETE:
 
950
  {
 
951
    assert(first_table == all_tables && first_table != 0);
 
952
    assert(select_lex->offset_limit == 0);
 
953
    unit->set_limit(select_lex);
 
954
 
 
955
    if (!(need_start_waiting= !wait_if_global_read_lock(session, 0, 1)))
 
956
    {
 
957
      res= 1;
 
958
      break;
 
959
    }
 
960
 
 
961
    res = mysql_delete(session, all_tables, select_lex->where,
 
962
                       &select_lex->order_list,
 
963
                       unit->select_limit_cnt, select_lex->options,
 
964
                       false);
 
965
    break;
 
966
  }
 
967
  case SQLCOM_DELETE_MULTI:
 
968
  {
 
969
    assert(first_table == all_tables && first_table != 0);
 
970
    TableList *aux_tables=
 
971
      (TableList *)session->lex->auxiliary_table_list.first;
 
972
    multi_delete *del_result;
 
973
 
 
974
    if (!(need_start_waiting= !wait_if_global_read_lock(session, 0, 1)))
 
975
    {
 
976
      res= 1;
 
977
      break;
 
978
    }
 
979
 
 
980
    if ((res= multi_delete_precheck(session, all_tables)))
 
981
      break;
 
982
 
 
983
    /* condition will be true on SP re-excuting */
 
984
    if (select_lex->item_list.elements != 0)
 
985
      select_lex->item_list.empty();
 
986
    if (session->add_item_to_list(new Item_null()))
 
987
      goto error;
 
988
 
 
989
    session->set_proc_info("init");
 
990
    if ((res= session->open_and_lock_tables(all_tables)))
 
991
      break;
 
992
 
 
993
    if ((res= mysql_multi_delete_prepare(session)))
 
994
      goto error;
 
995
 
 
996
    if (!session->is_fatal_error &&
 
997
        (del_result= new multi_delete(aux_tables, lex->table_count)))
 
998
    {
 
999
      res= mysql_select(session, &select_lex->ref_pointer_array,
 
1000
                        select_lex->get_table_list(),
 
1001
                        select_lex->with_wild,
 
1002
                        select_lex->item_list,
 
1003
                        select_lex->where,
 
1004
                        0, (order_st *)NULL, (order_st *)NULL, (Item *)NULL,
 
1005
                        select_lex->options | session->options | SELECT_NO_JOIN_CACHE | SELECT_NO_UNLOCK | OPTION_SETUP_TABLES_DONE,
 
1006
                        del_result, unit, select_lex);
 
1007
      res|= session->is_error();
 
1008
      if (res)
 
1009
        del_result->abort();
 
1010
      delete del_result;
 
1011
    }
 
1012
    else
 
1013
      res= true;                                // Error
 
1014
    break;
 
1015
  }
 
1016
  case SQLCOM_DROP_TABLE:
 
1017
  {
 
1018
    assert(first_table == all_tables && first_table != 0);
 
1019
    if (!lex->drop_temporary)
 
1020
    {
 
1021
      if (! session->endActiveTransaction())
 
1022
        goto error;
 
1023
    }
 
1024
    else
 
1025
    {
 
1026
      /* So that DROP TEMPORARY TABLE gets to binlog at commit/rollback */
 
1027
      session->options|= OPTION_KEEP_LOG;
 
1028
    }
 
1029
    /* DDL and binlog write order protected by LOCK_open */
 
1030
    res= mysql_rm_table(session, first_table, lex->drop_if_exists, lex->drop_temporary);
 
1031
  }
 
1032
  break;
 
1033
  case SQLCOM_SHOW_PROCESSLIST:
 
1034
    mysqld_list_processes(session, NULL, lex->verbose);
 
1035
    break;
 
1036
  case SQLCOM_CHANGE_DB:
 
1037
  {
 
1038
    LEX_STRING db_str= { (char *) select_lex->db, strlen(select_lex->db) };
 
1039
 
 
1040
    if (!mysql_change_db(session, &db_str, false))
 
1041
      session->my_ok();
 
1042
 
 
1043
    break;
 
1044
  }
 
1045
 
 
1046
  case SQLCOM_LOAD:
 
1047
  {
 
1048
    assert(first_table == all_tables && first_table != 0);
 
1049
    res= mysql_load(session, lex->exchange, first_table, lex->field_list,
 
1050
                    lex->update_list, lex->value_list, lex->duplicates, lex->ignore);
 
1051
    break;
 
1052
  }
 
1053
 
 
1054
  case SQLCOM_SET_OPTION:
 
1055
  {
 
1056
    List<set_var_base> *lex_var_list= &lex->var_list;
 
1057
 
 
1058
    if (session->open_and_lock_tables(all_tables))
 
1059
      goto error;
 
1060
    if (!(res= sql_set_variables(session, lex_var_list)))
 
1061
    {
 
1062
      session->my_ok();
 
1063
    }
 
1064
    else
 
1065
    {
 
1066
      /*
 
1067
        We encountered some sort of error, but no message was sent.
 
1068
        Send something semi-generic here since we don't know which
 
1069
        assignment in the list caused the error.
 
1070
      */
 
1071
      if (!session->is_error())
 
1072
        my_error(ER_WRONG_ARGUMENTS,MYF(0),"SET");
 
1073
      goto error;
 
1074
    }
 
1075
 
 
1076
    break;
 
1077
  }
 
1078
 
 
1079
  case SQLCOM_UNLOCK_TABLES:
 
1080
    /*
 
1081
      It is critical for mysqldump --single-transaction --master-data that
 
1082
      UNLOCK TABLES does not implicitely commit a connection which has only
 
1083
      done FLUSH TABLES WITH READ LOCK + BEGIN. If this assumption becomes
 
1084
      false, mysqldump will not work.
 
1085
    */
 
1086
    if (session->global_read_lock)
 
1087
      unlock_global_read_lock(session);
 
1088
    session->my_ok();
 
1089
    break;
 
1090
  case SQLCOM_CREATE_DB:
 
1091
  {
 
1092
    /*
 
1093
      As mysql_create_db() may modify HA_CREATE_INFO structure passed to
 
1094
      it, we need to use a copy of LEX::create_info to make execution
 
1095
      prepared statement- safe.
 
1096
    */
 
1097
    HA_CREATE_INFO create_info(lex->create_info);
 
1098
    if (! session->endActiveTransaction())
 
1099
    {
 
1100
      res= -1;
 
1101
      break;
 
1102
    }
 
1103
    char *alias;
 
1104
    if (!(alias=session->strmake(lex->name.str, lex->name.length)) ||
 
1105
        check_db_name(&lex->name))
 
1106
    {
 
1107
      my_error(ER_WRONG_DB_NAME, MYF(0), lex->name.str);
 
1108
      break;
 
1109
    }
 
1110
    res= mysql_create_db(session,(lex->name.str), &create_info);
 
1111
    break;
 
1112
  }
 
1113
  case SQLCOM_DROP_DB:
 
1114
  {
 
1115
    if (! session->endActiveTransaction())
 
1116
    {
 
1117
      res= -1;
 
1118
      break;
 
1119
    }
 
1120
    if (check_db_name(&lex->name))
 
1121
    {
 
1122
      my_error(ER_WRONG_DB_NAME, MYF(0), lex->name.str);
 
1123
      break;
 
1124
    }
 
1125
    if (session->inTransaction())
 
1126
    {
 
1127
      my_message(ER_LOCK_OR_ACTIVE_TRANSACTION, ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
 
1128
      goto error;
 
1129
    }
 
1130
    res= mysql_rm_db(session, lex->name.str, lex->drop_if_exists);
 
1131
    break;
 
1132
  }
 
1133
  case SQLCOM_ALTER_DB:
 
1134
  {
 
1135
    LEX_STRING *db= &lex->name;
 
1136
    HA_CREATE_INFO create_info(lex->create_info);
 
1137
    if (check_db_name(db))
 
1138
    {
 
1139
      my_error(ER_WRONG_DB_NAME, MYF(0), db->str);
 
1140
      break;
 
1141
    }
 
1142
    if (session->inTransaction())
 
1143
    {
 
1144
      my_message(ER_LOCK_OR_ACTIVE_TRANSACTION, ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
 
1145
      goto error;
 
1146
    }
 
1147
    res= mysql_alter_db(session, db->str, &create_info);
 
1148
    break;
 
1149
  }
 
1150
  case SQLCOM_SHOW_CREATE_DB:
 
1151
  {
 
1152
    if (check_db_name(&lex->name))
 
1153
    {
 
1154
      my_error(ER_WRONG_DB_NAME, MYF(0), lex->name.str);
 
1155
      break;
 
1156
    }
 
1157
    res= mysqld_show_create_db(session, lex->name.str,
 
1158
                               lex->create_info.options &
 
1159
                                 HA_LEX_CREATE_IF_NOT_EXISTS);
 
1160
    break;
 
1161
  }
 
1162
  case SQLCOM_FLUSH:
 
1163
  {
 
1164
    /*
 
1165
      reload_cache() will tell us if we are allowed to write to the
 
1166
      binlog or not.
 
1167
    */
 
1168
    if (!reload_cache(session, lex->type, first_table))
 
1169
    {
 
1170
      /*
 
1171
        We WANT to write and we CAN write.
 
1172
        ! we write after unlocking the table.
 
1173
      */
 
1174
      /*
 
1175
        Presumably, RESET and binlog writing doesn't require synchronization
 
1176
      */
 
1177
      write_bin_log(session, false, session->query, session->query_length);
 
1178
      session->my_ok();
 
1179
    }
 
1180
 
 
1181
    break;
 
1182
  }
 
1183
  case SQLCOM_KILL:
 
1184
  {
 
1185
    Item *it= (Item *)lex->value_list.head();
 
1186
 
 
1187
    if ((!it->fixed && it->fix_fields(lex->session, &it)) || it->check_cols(1))
 
1188
    {
 
1189
      my_message(ER_SET_CONSTANTS_ONLY, ER(ER_SET_CONSTANTS_ONLY),
 
1190
                 MYF(0));
 
1191
      goto error;
 
1192
    }
 
1193
    sql_kill(session, (ulong)it->val_int(), lex->type & ONLY_KILL_QUERY);
 
1194
    break;
 
1195
  }
 
1196
  case SQLCOM_BEGIN:
 
1197
    if (session->transaction.xid_state.xa_state != XA_NOTR)
 
1198
    {
 
1199
      my_error(ER_XAER_RMFAIL, MYF(0),
 
1200
               xa_state_names[session->transaction.xid_state.xa_state]);
 
1201
      break;
 
1202
    }
 
1203
    /*
 
1204
      Breakpoints for backup testing.
 
1205
    */
 
1206
    if (! session->startTransaction())
 
1207
      goto error;
 
1208
    session->my_ok();
 
1209
    break;
 
1210
  case SQLCOM_COMMIT:
 
1211
    if (! session->endTransaction(lex->tx_release ? COMMIT_RELEASE : lex->tx_chain ? COMMIT_AND_CHAIN : COMMIT))
 
1212
      goto error;
 
1213
    session->my_ok();
 
1214
    break;
 
1215
  case SQLCOM_ROLLBACK:
 
1216
    if (! session->endTransaction(lex->tx_release ? ROLLBACK_RELEASE : lex->tx_chain ? ROLLBACK_AND_CHAIN : ROLLBACK))
 
1217
      goto error;
 
1218
    session->my_ok();
 
1219
    break;
 
1220
  case SQLCOM_RELEASE_SAVEPOINT:
 
1221
  {
 
1222
    SAVEPOINT *sv;
 
1223
    for (sv=session->transaction.savepoints; sv; sv=sv->prev)
 
1224
    {
 
1225
      if (my_strnncoll(system_charset_info,
 
1226
                       (unsigned char *)lex->ident.str, lex->ident.length,
 
1227
                       (unsigned char *)sv->name, sv->length) == 0)
 
1228
        break;
 
1229
    }
 
1230
    if (sv)
 
1231
    {
 
1232
      if (ha_release_savepoint(session, sv))
 
1233
        res= true; // cannot happen
 
1234
      else
 
1235
        session->my_ok();
 
1236
      session->transaction.savepoints=sv->prev;
 
1237
    }
 
1238
    else
 
1239
      my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "SAVEPOINT", lex->ident.str);
 
1240
    break;
 
1241
  }
 
1242
  case SQLCOM_ROLLBACK_TO_SAVEPOINT:
 
1243
  {
 
1244
    SAVEPOINT *sv;
 
1245
    for (sv=session->transaction.savepoints; sv; sv=sv->prev)
 
1246
    {
 
1247
      if (my_strnncoll(system_charset_info,
 
1248
                       (unsigned char *)lex->ident.str, lex->ident.length,
 
1249
                       (unsigned char *)sv->name, sv->length) == 0)
 
1250
        break;
 
1251
    }
 
1252
    if (sv)
 
1253
    {
 
1254
      if (ha_rollback_to_savepoint(session, sv))
 
1255
        res= true; // cannot happen
 
1256
      else
 
1257
      {
 
1258
        if ((session->options & OPTION_KEEP_LOG) || session->transaction.all.modified_non_trans_table)
 
1259
          push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
1260
                       ER_WARNING_NOT_COMPLETE_ROLLBACK,
 
1261
                       ER(ER_WARNING_NOT_COMPLETE_ROLLBACK));
 
1262
        session->my_ok();
 
1263
      }
 
1264
      session->transaction.savepoints=sv;
 
1265
    }
 
1266
    else
 
1267
      my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "SAVEPOINT", lex->ident.str);
 
1268
    break;
 
1269
  }
 
1270
  case SQLCOM_SAVEPOINT:
 
1271
    if (!(session->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))
 
1272
      session->my_ok();
 
1273
    else
 
1274
    {
 
1275
      SAVEPOINT **sv, *newsv;
 
1276
      for (sv=&session->transaction.savepoints; *sv; sv=&(*sv)->prev)
 
1277
      {
 
1278
        if (my_strnncoll(system_charset_info,
 
1279
                         (unsigned char *)lex->ident.str, lex->ident.length,
 
1280
                         (unsigned char *)(*sv)->name, (*sv)->length) == 0)
 
1281
          break;
 
1282
      }
 
1283
      if (*sv) /* old savepoint of the same name exists */
 
1284
      {
 
1285
        newsv=*sv;
 
1286
        ha_release_savepoint(session, *sv); // it cannot fail
 
1287
        *sv=(*sv)->prev;
 
1288
      }
 
1289
      else if ((newsv=(SAVEPOINT *) alloc_root(&session->transaction.mem_root,
 
1290
                                               savepoint_alloc_size)) == 0)
 
1291
      {
 
1292
        my_error(ER_OUT_OF_RESOURCES, MYF(0));
 
1293
        break;
 
1294
      }
 
1295
      newsv->name=strmake_root(&session->transaction.mem_root,
 
1296
                               lex->ident.str, lex->ident.length);
 
1297
      newsv->length=lex->ident.length;
 
1298
      /*
 
1299
        if we'll get an error here, don't add new savepoint to the list.
 
1300
        we'll lose a little bit of memory in transaction mem_root, but it'll
 
1301
        be free'd when transaction ends anyway
 
1302
      */
 
1303
      if (ha_savepoint(session, newsv))
 
1304
        res= true;
 
1305
      else
 
1306
      {
 
1307
        newsv->prev=session->transaction.savepoints;
 
1308
        session->transaction.savepoints=newsv;
 
1309
        session->my_ok();
 
1310
      }
 
1311
    }
 
1312
    break;
 
1313
  default:
 
1314
    /*
 
1315
     * This occurs now because we have extracted some commands in
 
1316
     * to their own classes and thus there is no matching case
 
1317
     * label in this switch statement for those commands. Pretty soon
 
1318
     * this entire switch statement will be gone along with this 
 
1319
     * comment...
 
1320
     */
 
1321
    comm_not_executed= true;
 
1322
    break;
 
1323
  }
 
1324
  /*
 
1325
   * The following conditional statement is only temporary until
 
1326
   * the mongo switch statement that occurs afterwards has been
 
1327
   * fully removed. Once that switch statement is gone, every
 
1328
   * command will have its own class and we won't need this
 
1329
   * check.
 
1330
   */
 
1331
  if (comm_not_executed)
 
1332
  {
 
1333
    /* now we are ready to execute the command */
 
1334
    res= lex->command->execute();
 
1335
  }
 
1336
 
480
1337
  session->set_proc_info("query end");
 
1338
 
481
1339
  /*
482
1340
    The return value for ROW_COUNT() is "implementation dependent" if the
483
1341
    statement is not DELETE, INSERT or UPDATE, but -1 is what JDBC and ODBC
484
1342
    wants. We also keep the last value in case of SQLCOM_CALL or
485
1343
    SQLCOM_EXECUTE.
486
1344
  */
487
 
  if (! (sql_command_flags[lex->sql_command].test(CF_BIT_HAS_ROW_COUNT)))
488
 
  {
 
1345
  if (!(sql_command_flags[lex->sql_command].test(CF_BIT_HAS_ROW_COUNT)))
489
1346
    session->row_count_func= -1;
 
1347
 
 
1348
  goto finish;
 
1349
 
 
1350
error:
 
1351
  res= true;
 
1352
 
 
1353
finish:
 
1354
  if (need_start_waiting)
 
1355
  {
 
1356
    /*
 
1357
      Release the protection against the global read lock and wake
 
1358
      everyone, who might want to set a global read lock.
 
1359
    */
 
1360
    start_waiting_global_read_lock(session);
490
1361
  }
491
 
 
492
 
  return (res || session->is_error());
 
1362
  return(res || session->is_error());
493
1363
}
 
1364
 
494
1365
bool execute_sqlcom_select(Session *session, TableList *all_tables)
495
1366
{
496
1367
  LEX   *lex= session->lex;
503
1374
      param->select_limit=
504
1375
        new Item_int((uint64_t) session->variables.select_limit);
505
1376
  }
506
 
  if (not (res= session->openTablesLock(all_tables)))
 
1377
  if (!(res= session->open_and_lock_tables(all_tables)))
507
1378
  {
508
1379
    if (lex->describe)
509
1380
    {
514
1385
        even if the query itself redirects the output.
515
1386
      */
516
1387
      if (!(result= new select_send()))
517
 
        return true;
 
1388
        return true;                               /* purecov: inspected */
518
1389
      session->send_explain_fields(result);
519
 
      optimizer::ExplainPlan planner;
520
 
      res= planner.explainUnion(session, &session->lex->unit, result);
 
1390
      res= mysql_explain_union(session, &session->lex->unit, result);
521
1391
      if (lex->describe & DESCRIBE_EXTENDED)
522
1392
      {
523
1393
        char buff[1024];
537
1407
    else
538
1408
    {
539
1409
      if (!result && !(result= new select_send()))
540
 
        return true;
541
 
 
542
 
      /* Init the Query Cache plugin */
543
 
      plugin::QueryCache::prepareResultset(session); 
 
1410
        return true;                               /* purecov: inspected */
544
1411
      res= handle_select(session, lex, result, 0);
545
 
      /* Send the Resultset to the cache */
546
 
      plugin::QueryCache::setResultset(session); 
547
 
 
548
1412
      if (result != lex->result)
549
1413
        delete result;
550
1414
    }
698
1562
  */
699
1563
  if ((var= get_system_var(session, OPT_SESSION, tmp, null_lex_string)))
700
1564
  {
701
 
    end+= snprintf(buff, sizeof(buff), "@@session.%s", var_name);
 
1565
    end+= sprintf(buff, "@@session.%s", var_name);
702
1566
    var->set_name(buff, end-buff, system_charset_info);
703
1567
    session->add_item_to_list(var);
704
1568
  }
706
1570
}
707
1571
 
708
1572
 
 
1573
void mysql_init_multi_delete(LEX *lex)
 
1574
{
 
1575
  lex->sql_command=  SQLCOM_DELETE_MULTI;
 
1576
  mysql_init_select(lex);
 
1577
  lex->select_lex.select_limit= 0;
 
1578
  lex->unit.select_limit_cnt= HA_POS_ERROR;
 
1579
  lex->select_lex.table_list.save_and_clear(&lex->auxiliary_table_list);
 
1580
  lex->lock_option= TL_READ;
 
1581
  lex->query_tables= 0;
 
1582
  lex->query_tables_last= &lex->query_tables;
 
1583
}
 
1584
 
 
1585
 
709
1586
/**
710
1587
  Parse a query.
711
1588
 
712
1589
  @param       session     Current thread
713
1590
  @param       inBuf   Begining of the query text
714
1591
  @param       length  Length of the query text
 
1592
  @param[out]  found_semicolon For multi queries, position of the character of
 
1593
                               the next query in the query text.
715
1594
*/
716
1595
 
717
 
void mysql_parse(Session *session, const char *inBuf, uint32_t length)
 
1596
void mysql_parse(Session *session, const char *inBuf, uint32_t length,
 
1597
                 const char ** found_semicolon)
718
1598
{
719
 
  boost::posix_time::ptime start_time=boost::posix_time::microsec_clock::local_time();
720
 
  session->lex->start(session);
721
 
 
 
1599
  /*
 
1600
    Warning.
 
1601
    The purpose of query_cache_send_result_to_client() is to lookup the
 
1602
    query in the query cache first, to avoid parsing and executing it.
 
1603
    So, the natural implementation would be to:
 
1604
    - first, call query_cache_send_result_to_client,
 
1605
    - second, if caching failed, initialise the lexical and syntactic parser.
 
1606
    The problem is that the query cache depends on a clean initialization
 
1607
    of (among others) lex->safe_to_cache_query and session->server_status,
 
1608
    which are reset respectively in
 
1609
    - lex_start()
 
1610
    - mysql_reset_session_for_next_command()
 
1611
    So, initializing the lexical analyser *before* using the query cache
 
1612
    is required for the cache to work properly.
 
1613
    FIXME: cleanup the dependencies in the code to simplify this.
 
1614
  */
 
1615
  lex_start(session);
722
1616
  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
 
  {
 
1617
 
 
1618
  {
 
1619
    LEX *lex= session->lex;
 
1620
 
 
1621
    Lex_input_stream lip(session, inBuf, length);
 
1622
 
 
1623
    bool err= parse_sql(session, &lip);
 
1624
    *found_semicolon= lip.found_semicolon;
 
1625
 
 
1626
    if (!err)
741
1627
    {
742
 
      if (not session->is_error())
743
1628
      {
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
 
        {
 
1629
        if (! session->is_error())
 
1630
        {
 
1631
          /*
 
1632
            Binlog logs a string starting from session->query and having length
 
1633
            session->query_length; so we set session->query_length correctly (to not
 
1634
            log several statements in one event, when we executed only first).
 
1635
            We set it to not see the ';' (otherwise it would get into binlog
 
1636
            and Query_log_event::print() would give ';;' output).
 
1637
            This also helps display only the current query in SHOW
 
1638
            PROCESSLIST.
 
1639
            Note that we don't need LOCK_thread_count to modify query_length.
 
1640
          */
 
1641
          if (*found_semicolon &&
 
1642
              (session->query_length= (ulong)(*found_semicolon - session->query)))
 
1643
            session->query_length--;
 
1644
          /* Actually execute the query */
751
1645
          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);
 
1646
        }
760
1647
      }
761
1648
    }
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();
 
1649
    else
 
1650
    {
 
1651
      assert(session->is_error());
 
1652
    }
 
1653
    lex->unit.cleanup();
 
1654
    session->set_proc_info("freeing items");
 
1655
    session->end_statement();
 
1656
    session->cleanup_after_query();
 
1657
  }
 
1658
 
 
1659
  return;
773
1660
}
774
1661
 
775
1662
 
792
1679
{
793
1680
  register CreateField *new_field;
794
1681
  LEX  *lex= session->lex;
795
 
  statement::AlterTable *statement= (statement::AlterTable *)lex->statement;
796
1682
 
797
1683
  if (check_identifier_name(field_name, ER_TOO_LONG_IDENT))
798
 
    return true;
 
1684
    return(1);                          /* purecov: inspected */
799
1685
 
800
1686
  if (type_modifier & PRI_KEY_FLAG)
801
1687
  {
804
1690
    key= new Key(Key::PRIMARY, null_lex_str,
805
1691
                      &default_key_create_info,
806
1692
                      0, lex->col_list);
807
 
    statement->alter_info.key_list.push_back(key);
 
1693
    lex->alter_info.key_list.push_back(key);
808
1694
    lex->col_list.empty();
809
1695
  }
810
1696
  if (type_modifier & (UNIQUE_FLAG | UNIQUE_KEY_FLAG))
814
1700
    key= new Key(Key::UNIQUE, null_lex_str,
815
1701
                 &default_key_create_info, 0,
816
1702
                 lex->col_list);
817
 
    statement->alter_info.key_list.push_back(key);
 
1703
    lex->alter_info.key_list.push_back(key);
818
1704
    lex->col_list.empty();
819
1705
  }
820
1706
 
832
1718
         type == DRIZZLE_TYPE_TIMESTAMP))
833
1719
    {
834
1720
      my_error(ER_INVALID_DEFAULT, MYF(0), field_name->str);
835
 
      return true;
 
1721
      return(1);
836
1722
    }
837
1723
    else if (default_value->type() == Item::NULL_ITEM)
838
1724
    {
841
1727
          NOT_NULL_FLAG)
842
1728
      {
843
1729
        my_error(ER_INVALID_DEFAULT, MYF(0), field_name->str);
844
 
        return true;
 
1730
        return(1);
845
1731
      }
846
1732
    }
847
1733
    else if (type_modifier & AUTO_INCREMENT_FLAG)
848
1734
    {
849
1735
      my_error(ER_INVALID_DEFAULT, MYF(0), field_name->str);
850
 
      return true;
 
1736
      return(1);
851
1737
    }
852
1738
  }
853
1739
 
854
1740
  if (on_update_value && type != DRIZZLE_TYPE_TIMESTAMP)
855
1741
  {
856
1742
    my_error(ER_INVALID_ON_UPDATE, MYF(0), field_name->str);
857
 
    return true;
 
1743
    return(1);
858
1744
  }
859
1745
 
860
1746
  if (!(new_field= new CreateField()) ||
861
1747
      new_field->init(session, field_name->str, type, length, decimals, type_modifier,
862
1748
                      default_value, on_update_value, comment, change,
863
1749
                      interval_list, cs, 0, column_format))
864
 
    return true;
 
1750
    return(1);
865
1751
 
866
 
  statement->alter_info.create_list.push_back(new_field);
 
1752
  lex->alter_info.create_list.push_back(new_field);
867
1753
  lex->last_field=new_field;
868
 
 
869
 
  return false;
 
1754
  return(0);
870
1755
}
871
1756
 
872
1757
 
878
1763
}
879
1764
 
880
1765
/**
 
1766
  save order by and tables in own lists.
 
1767
*/
 
1768
 
 
1769
bool add_to_list(Session *session, SQL_LIST &list,Item *item,bool asc)
 
1770
{
 
1771
  order_st *order;
 
1772
  if (!(order = (order_st *) session->alloc(sizeof(order_st))))
 
1773
    return(1);
 
1774
  order->item_ptr= item;
 
1775
  order->item= &order->item_ptr;
 
1776
  order->asc = asc;
 
1777
  order->free_me=0;
 
1778
  order->used=0;
 
1779
  order->counter_used= 0;
 
1780
  list.link_in_list((unsigned char*) order,(unsigned char**) &order->next);
 
1781
  return(0);
 
1782
}
 
1783
 
 
1784
 
 
1785
/**
881
1786
  Add a table to list of used tables.
882
1787
 
883
1788
  @param table          Table to add
897
1802
*/
898
1803
 
899
1804
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)
 
1805
                                             Table_ident *table,
 
1806
                                             LEX_STRING *alias,
 
1807
                                             uint32_t table_options,
 
1808
                                             thr_lock_type lock_type,
 
1809
                                             List<Index_hint> *index_hints_arg,
 
1810
                                             LEX_STRING *option)
906
1811
{
907
 
  TableList *ptr;
 
1812
  register TableList *ptr;
908
1813
  TableList *previous_table_ref; /* The table preceding the current one. */
909
1814
  char *alias_str;
910
1815
  LEX *lex= session->lex;
912
1817
  if (!table)
913
1818
    return NULL;                                // End of memory
914
1819
  alias_str= alias ? alias->str : table->table.str;
915
 
  if (! table_options.test(TL_OPTION_ALIAS) &&
 
1820
  if (!test(table_options & TL_OPTION_ALIAS) &&
916
1821
      check_table_name(table->table.str, table->table.length))
917
1822
  {
918
1823
    my_error(ER_WRONG_TABLE_NAME, MYF(0), table->table.str);
919
1824
    return NULL;
920
1825
  }
921
1826
 
922
 
  if (table->is_derived_table() == false && table->db.str)
 
1827
  if (table->is_derived_table() == false && table->db.str &&
 
1828
      check_db_name(&table->db))
923
1829
  {
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
 
    }
 
1830
    my_error(ER_WRONG_DB_NAME, MYF(0), table->db.str);
 
1831
    return NULL;
933
1832
  }
934
1833
 
935
1834
  if (!alias)                                   /* Alias is case sensitive */
944
1843
      return NULL;
945
1844
  }
946
1845
  if (!(ptr = (TableList *) session->calloc(sizeof(TableList))))
947
 
    return NULL;
948
 
 
 
1846
    return NULL;                                /* purecov: inspected */
949
1847
  if (table->db.str)
950
1848
  {
951
 
    ptr->setIsFqtn(true);
952
 
    ptr->setSchemaName(table->db.str);
 
1849
    ptr->is_fqtn= true;
 
1850
    ptr->db= table->db.str;
953
1851
    ptr->db_length= table->db.length;
954
1852
  }
955
 
  else if (lex->copy_db_to(ptr->getSchemaNamePtr(), &ptr->db_length))
 
1853
  else if (lex->copy_db_to(&ptr->db, &ptr->db_length))
956
1854
    return NULL;
957
1855
  else
958
 
    ptr->setIsFqtn(false);
 
1856
    ptr->is_fqtn= false;
959
1857
 
960
1858
  ptr->alias= alias_str;
961
 
  ptr->setIsAlias(alias ? true : false);
962
 
  ptr->setTableName(table->table.str);
 
1859
  ptr->is_alias= alias ? true : false;
 
1860
  if (table->table.length)
 
1861
    table->table.length= my_casedn_str(files_charset_info, table->table.str);
 
1862
  ptr->table_name=table->table.str;
963
1863
  ptr->table_name_length=table->table.length;
964
1864
  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);
 
1865
  ptr->updating=    test(table_options & TL_OPTION_UPDATING);
 
1866
  ptr->force_index= test(table_options & TL_OPTION_FORCE_INDEX);
 
1867
  ptr->ignore_leaves= test(table_options & TL_OPTION_IGNORE_LEAVES);
967
1868
  ptr->derived=     table->sel;
 
1869
  if (!ptr->derived && !my_strcasecmp(system_charset_info, ptr->db,
 
1870
                                      INFORMATION_SCHEMA_NAME.c_str()))
 
1871
  {
 
1872
    InfoSchemaTable *schema_table= find_schema_table(ptr->table_name);
 
1873
    if (!schema_table ||
 
1874
        (schema_table->isHidden() &&
 
1875
         ((sql_command_flags[lex->sql_command].test(CF_BIT_STATUS_COMMAND)) == 0 ||
 
1876
          /*
 
1877
            this check is used for show columns|keys from I_S hidden table
 
1878
          */
 
1879
          lex->sql_command == SQLCOM_SHOW_FIELDS ||
 
1880
          lex->sql_command == SQLCOM_SHOW_KEYS)))
 
1881
    {
 
1882
      my_error(ER_UNKNOWN_TABLE, MYF(0),
 
1883
               ptr->table_name, INFORMATION_SCHEMA_NAME.c_str());
 
1884
      return NULL;
 
1885
    }
 
1886
    ptr->schema_table_name= ptr->table_name;
 
1887
    ptr->schema_table= schema_table;
 
1888
  }
968
1889
  ptr->select_lex=  lex->current_select;
969
1890
  ptr->index_hints= index_hints_arg;
970
1891
  ptr->option= option ? option->str : 0;
977
1898
         tables=tables->next_local)
978
1899
    {
979
1900
      if (!my_strcasecmp(table_alias_charset, alias_str, tables->alias) &&
980
 
          !strcasecmp(ptr->getSchemaName(), tables->getSchemaName()))
 
1901
          !strcmp(ptr->db, tables->db))
981
1902
      {
982
 
        my_error(ER_NONUNIQ_TABLE, MYF(0), alias_str);
983
 
        return NULL;
 
1903
        my_error(ER_NONUNIQ_TABLE, MYF(0), alias_str); /* purecov: tested */
 
1904
        return NULL;                            /* purecov: tested */
984
1905
      }
985
1906
    }
986
1907
  }
1046
1967
  if (!(ptr= (TableList*) session->calloc(ALIGN_SIZE(sizeof(TableList))+
1047
1968
                                       sizeof(nested_join_st))))
1048
1969
    return true;
1049
 
  ptr->setNestedJoin(((nested_join_st*) ((unsigned char*) ptr + ALIGN_SIZE(sizeof(TableList)))));
1050
 
  nested_join= ptr->getNestedJoin();
 
1970
  nested_join= ptr->nested_join=
 
1971
    ((nested_join_st*) ((unsigned char*) ptr + ALIGN_SIZE(sizeof(TableList))));
 
1972
 
1051
1973
  join_list->push_front(ptr);
1052
 
  ptr->setEmbedding(embedding);
1053
 
  ptr->setJoinList(join_list);
 
1974
  ptr->embedding= embedding;
 
1975
  ptr->join_list= join_list;
1054
1976
  ptr->alias= (char*) "(nested_join)";
1055
1977
  embedding= ptr;
1056
1978
  join_list= &nested_join->join_list;
1080
2002
 
1081
2003
  assert(embedding);
1082
2004
  ptr= embedding;
1083
 
  join_list= ptr->getJoinList();
1084
 
  embedding= ptr->getEmbedding();
1085
 
  nested_join= ptr->getNestedJoin();
 
2005
  join_list= ptr->join_list;
 
2006
  embedding= ptr->embedding;
 
2007
  nested_join= ptr->nested_join;
1086
2008
  if (nested_join->join_list.elements == 1)
1087
2009
  {
1088
2010
    TableList *embedded= nested_join->join_list.head();
1089
2011
    join_list->pop();
1090
 
    embedded->setJoinList(join_list);
1091
 
    embedded->setEmbedding(embedding);
 
2012
    embedded->join_list= join_list;
 
2013
    embedded->embedding= embedding;
1092
2014
    join_list->push_front(embedded);
1093
2015
    ptr= embedded;
1094
2016
  }
1121
2043
  List<TableList> *embedded_list;
1122
2044
 
1123
2045
  if (!(ptr= (TableList*) session->calloc(ALIGN_SIZE(sizeof(TableList))+
1124
 
                                          sizeof(nested_join_st))))
 
2046
                                       sizeof(nested_join_st))))
1125
2047
    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);
 
2048
  nested_join= ptr->nested_join=
 
2049
    ((nested_join_st*) ((unsigned char*) ptr + ALIGN_SIZE(sizeof(TableList))));
 
2050
 
 
2051
  ptr->embedding= embedding;
 
2052
  ptr->join_list= join_list;
1130
2053
  ptr->alias= (char*) "(nest_last_join)";
1131
2054
  embedded_list= &nested_join->join_list;
1132
2055
  embedded_list->empty();
1134
2057
  for (uint32_t i=0; i < 2; i++)
1135
2058
  {
1136
2059
    TableList *table= join_list->pop();
1137
 
    table->setJoinList(embedded_list);
1138
 
    table->setEmbedding(ptr);
 
2060
    table->join_list= embedded_list;
 
2061
    table->embedding= ptr;
1139
2062
    embedded_list->push_back(table);
1140
2063
    if (table->natural_join)
1141
2064
    {
1171
2094
void Select_Lex::add_joined_table(TableList *table)
1172
2095
{
1173
2096
  join_list->push_front(table);
1174
 
  table->setJoinList(join_list);
1175
 
  table->setEmbedding(embedding);
 
2097
  table->join_list= join_list;
 
2098
  table->embedding= embedding;
1176
2099
}
1177
2100
 
1178
2101
 
1232
2155
 
1233
2156
void Select_Lex::set_lock_for_tables(thr_lock_type lock_type)
1234
2157
{
 
2158
  bool for_update= lock_type >= TL_READ_NO_INSERT;
 
2159
 
1235
2160
  for (TableList *tables= (TableList*) table_list.first;
1236
2161
       tables;
1237
2162
       tables= tables->next_local)
1238
2163
  {
1239
2164
    tables->lock_type= lock_type;
 
2165
    tables->updating=  for_update;
1240
2166
  }
 
2167
  return;
1241
2168
}
1242
2169
 
1243
2170
 
1248
2175
    This object is created for any union construct containing a union
1249
2176
    operation and also for any single select union construct of the form
1250
2177
    @verbatim
1251
 
    (SELECT ... ORDER BY order_list [LIMIT n]) ORDER BY ...
 
2178
    (SELECT ... order_st BY order_list [LIMIT n]) order_st BY ...
1252
2179
    @endvarbatim
1253
2180
    or of the form
1254
2181
    @varbatim
1255
 
    (SELECT ... ORDER BY LIMIT n) ORDER BY ...
 
2182
    (SELECT ... order_st BY LIMIT n) order_st BY ...
1256
2183
    @endvarbatim
1257
2184
 
1258
2185
  @param session_arg               thread handle
1283
2210
  fake_select_lex->select_limit= 0;
1284
2211
 
1285
2212
  fake_select_lex->context.outer_context=first_sl->context.outer_context;
1286
 
  /* allow item list resolving in fake select for ORDER BY */
 
2213
  /* allow item list resolving in fake select for order_st BY */
1287
2214
  fake_select_lex->context.resolve_in_select_list= true;
1288
2215
  fake_select_lex->context.select_lex= fake_select_lex;
1289
2216
 
1291
2218
  {
1292
2219
    /*
1293
2220
      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]
 
2221
      (SELECT ... order_st BY list [LIMIT n]) order_st BY order_list [LIMIT m],
 
2222
      (SELECT ... LIMIT n) order_st BY order_list [LIMIT m]
1296
2223
      just before the parser starts processing order_list
1297
2224
    */
1298
2225
    global_parameters= fake_select_lex;
1415
2342
 
1416
2343
 
1417
2344
/**
 
2345
  Reload/resets privileges and the different caches.
 
2346
 
 
2347
  @param session Thread handler (can be NULL!)
 
2348
  @param options What should be reset/reloaded (tables, privileges, slave...)
 
2349
  @param tables Tables to flush (if any)
 
2350
  @param write_to_binlog True if we can write to the binlog.
 
2351
 
 
2352
  @note Depending on 'options', it may be very bad to write the
 
2353
    query to the binlog (e.g. FLUSH SLAVE); this is a
 
2354
    pointer where reload_cache() will put 0 if
 
2355
    it thinks we really should not write to the binlog.
 
2356
    Otherwise it will put 1.
 
2357
 
 
2358
  @return Error status code
 
2359
    @retval 0 Ok
 
2360
    @retval !=0  Error; session->killed is set or session->is_error() is true
 
2361
*/
 
2362
 
 
2363
bool reload_cache(Session *session, ulong options, TableList *tables)
 
2364
{
 
2365
  bool result=0;
 
2366
 
 
2367
  if (options & REFRESH_LOG)
 
2368
  {
 
2369
    if (ha_flush_logs(NULL))
 
2370
      result=1;
 
2371
  }
 
2372
  /*
 
2373
    Note that if REFRESH_READ_LOCK bit is set then REFRESH_TABLES is set too
 
2374
    (see sql_yacc.yy)
 
2375
  */
 
2376
  if (options & (REFRESH_TABLES | REFRESH_READ_LOCK))
 
2377
  {
 
2378
    if ((options & REFRESH_READ_LOCK) && session)
 
2379
    {
 
2380
      if (lock_global_read_lock(session))
 
2381
        return true;                               // Killed
 
2382
      result= close_cached_tables(session, tables, (options & REFRESH_FAST) ?
 
2383
                                  false : true, true);
 
2384
      if (make_global_read_lock_block_commit(session)) // Killed
 
2385
      {
 
2386
        /* Don't leave things in a half-locked state */
 
2387
        unlock_global_read_lock(session);
 
2388
 
 
2389
        return true;
 
2390
      }
 
2391
    }
 
2392
    else
 
2393
      result= close_cached_tables(session, tables, (options & REFRESH_FAST) ?
 
2394
                                  false : true, false);
 
2395
  }
 
2396
  if (session && (options & REFRESH_STATUS))
 
2397
    session->refresh_status();
 
2398
 
 
2399
 return result;
 
2400
}
 
2401
 
 
2402
 
 
2403
/**
 
2404
  kill on thread.
 
2405
 
 
2406
  @param session                        Thread class
 
2407
  @param id                     Thread id
 
2408
  @param only_kill_query        Should it kill the query or the connection
 
2409
 
 
2410
  @note
 
2411
    This is written such that we have a short lock on LOCK_thread_count
 
2412
*/
 
2413
 
 
2414
static unsigned int
 
2415
kill_one_thread(Session *, ulong id, bool only_kill_query)
 
2416
{
 
2417
  Session *tmp= NULL;
 
2418
  uint32_t error=ER_NO_SUCH_THREAD;
 
2419
  pthread_mutex_lock(&LOCK_thread_count); // For unlink from list
 
2420
  
 
2421
  for( vector<Session*>::iterator it= session_list.begin(); it != session_list.end(); ++it )
 
2422
  {
 
2423
    if ((*it)->thread_id == id)
 
2424
    {
 
2425
      tmp= *it;
 
2426
      pthread_mutex_lock(&tmp->LOCK_delete);    // Lock from delete
 
2427
      break;
 
2428
    }
 
2429
  }
 
2430
  pthread_mutex_unlock(&LOCK_thread_count);
 
2431
  if (tmp)
 
2432
  {
 
2433
    tmp->awake(only_kill_query ? Session::KILL_QUERY : Session::KILL_CONNECTION);
 
2434
    error=0;
 
2435
    pthread_mutex_unlock(&tmp->LOCK_delete);
 
2436
  }
 
2437
  return(error);
 
2438
}
 
2439
 
 
2440
 
 
2441
/*
 
2442
  kills a thread and sends response
 
2443
 
 
2444
  SYNOPSIS
 
2445
    sql_kill()
 
2446
    session                     Thread class
 
2447
    id                  Thread id
 
2448
    only_kill_query     Should it kill the query or the connection
 
2449
*/
 
2450
 
 
2451
void sql_kill(Session *session, ulong id, bool only_kill_query)
 
2452
{
 
2453
  uint32_t error;
 
2454
  if (!(error= kill_one_thread(session, id, only_kill_query)))
 
2455
    session->my_ok();
 
2456
  else
 
2457
    my_error(error, MYF(0), id);
 
2458
}
 
2459
 
 
2460
 
 
2461
/** If pointer is not a null pointer, append filename to it. */
 
2462
 
 
2463
static bool append_file_to_dir(Session *session, const char **filename_ptr,
 
2464
                               const char *table_name)
 
2465
{
 
2466
  char buff[FN_REFLEN],*ptr, *end;
 
2467
  if (!*filename_ptr)
 
2468
    return 0;                                   // nothing to do
 
2469
 
 
2470
  /* Check that the filename is not too long and it's a hard path */
 
2471
  if (strlen(*filename_ptr)+strlen(table_name) >= FN_REFLEN-1 ||
 
2472
      !test_if_hard_path(*filename_ptr))
 
2473
  {
 
2474
    my_error(ER_WRONG_TABLE_NAME, MYF(0), *filename_ptr);
 
2475
    return 1;
 
2476
  }
 
2477
  /* Fix is using unix filename format on dos */
 
2478
  strcpy(buff,*filename_ptr);
 
2479
  end=convert_dirname(buff, *filename_ptr, NULL);
 
2480
  if (!(ptr= (char*) session->alloc((size_t) (end-buff) + strlen(table_name)+1)))
 
2481
    return 1;                                   // End of memory
 
2482
  *filename_ptr=ptr;
 
2483
  sprintf(ptr,"%s%s",buff,table_name);
 
2484
  return 0;
 
2485
}
 
2486
 
 
2487
 
 
2488
/**
1418
2489
  Check if the select is a simple select (not an union).
1419
2490
 
1420
2491
  @retval
1511
2582
  return(false);
1512
2583
}
1513
2584
 
 
2585
/**
 
2586
  Multi delete query pre-check.
 
2587
 
 
2588
  @param session                        Thread handler
 
2589
  @param tables         Global/local table list
 
2590
 
 
2591
  @retval
 
2592
    false OK
 
2593
  @retval
 
2594
    true  error
 
2595
*/
 
2596
 
 
2597
bool multi_delete_precheck(Session *session, TableList *)
 
2598
{
 
2599
  Select_Lex *select_lex= &session->lex->select_lex;
 
2600
  TableList **save_query_tables_own_last= session->lex->query_tables_own_last;
 
2601
 
 
2602
  session->lex->query_tables_own_last= 0;
 
2603
  session->lex->query_tables_own_last= save_query_tables_own_last;
 
2604
 
 
2605
  if ((session->options & OPTION_SAFE_UPDATES) && !select_lex->where)
 
2606
  {
 
2607
    my_message(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE,
 
2608
               ER(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE), MYF(0));
 
2609
    return(true);
 
2610
  }
 
2611
  return(false);
 
2612
}
 
2613
 
 
2614
 
 
2615
/*
 
2616
  Given a table in the source list, find a correspondent table in the
 
2617
  table references list.
 
2618
 
 
2619
  @param lex Pointer to LEX representing multi-delete.
 
2620
  @param src Source table to match.
 
2621
  @param ref Table references list.
 
2622
 
 
2623
  @remark The source table list (tables listed before the FROM clause
 
2624
  or tables listed in the FROM clause before the USING clause) may
 
2625
  contain table names or aliases that must match unambiguously one,
 
2626
  and only one, table in the target table list (table references list,
 
2627
  after FROM/USING clause).
 
2628
 
 
2629
  @return Matching table, NULL otherwise.
 
2630
*/
 
2631
 
 
2632
static TableList *multi_delete_table_match(LEX *, TableList *tbl,
 
2633
                                           TableList *tables)
 
2634
{
 
2635
  TableList *match= NULL;
 
2636
 
 
2637
  for (TableList *elem= tables; elem; elem= elem->next_local)
 
2638
  {
 
2639
    int cmp;
 
2640
 
 
2641
    if (tbl->is_fqtn && elem->is_alias)
 
2642
      continue; /* no match */
 
2643
    if (tbl->is_fqtn && elem->is_fqtn)
 
2644
      cmp= my_strcasecmp(table_alias_charset, tbl->table_name, elem->table_name) ||
 
2645
           strcmp(tbl->db, elem->db);
 
2646
    else if (elem->is_alias)
 
2647
      cmp= my_strcasecmp(table_alias_charset, tbl->alias, elem->alias);
 
2648
    else
 
2649
      cmp= my_strcasecmp(table_alias_charset, tbl->table_name, elem->table_name) ||
 
2650
           strcmp(tbl->db, elem->db);
 
2651
 
 
2652
    if (cmp)
 
2653
      continue;
 
2654
 
 
2655
    if (match)
 
2656
    {
 
2657
      my_error(ER_NONUNIQ_TABLE, MYF(0), elem->alias);
 
2658
      return NULL;
 
2659
    }
 
2660
 
 
2661
    match= elem;
 
2662
  }
 
2663
 
 
2664
  if (!match)
 
2665
    my_error(ER_UNKNOWN_TABLE, MYF(0), tbl->table_name, "MULTI DELETE");
 
2666
 
 
2667
  return(match);
 
2668
}
 
2669
 
 
2670
 
 
2671
/**
 
2672
  Link tables in auxilary table list of multi-delete with corresponding
 
2673
  elements in main table list, and set proper locks for them.
 
2674
 
 
2675
  @param lex   pointer to LEX representing multi-delete
 
2676
 
 
2677
  @retval
 
2678
    false   success
 
2679
  @retval
 
2680
    true    error
 
2681
*/
 
2682
 
 
2683
bool multi_delete_set_locks_and_link_aux_tables(LEX *lex)
 
2684
{
 
2685
  TableList *tables= (TableList*)lex->select_lex.table_list.first;
 
2686
  TableList *target_tbl;
 
2687
 
 
2688
  lex->table_count= 0;
 
2689
 
 
2690
  for (target_tbl= (TableList *)lex->auxiliary_table_list.first;
 
2691
       target_tbl; target_tbl= target_tbl->next_local)
 
2692
  {
 
2693
    lex->table_count++;
 
2694
    /* All tables in aux_tables must be found in FROM PART */
 
2695
    TableList *walk= multi_delete_table_match(lex, target_tbl, tables);
 
2696
    if (!walk)
 
2697
      return(true);
 
2698
    if (!walk->derived)
 
2699
    {
 
2700
      target_tbl->table_name= walk->table_name;
 
2701
      target_tbl->table_name_length= walk->table_name_length;
 
2702
    }
 
2703
    walk->updating= target_tbl->updating;
 
2704
    walk->lock_type= target_tbl->lock_type;
 
2705
    target_tbl->correspondent_table= walk;      // Remember corresponding table
 
2706
  }
 
2707
  return(false);
 
2708
}
 
2709
 
1514
2710
 
1515
2711
/**
1516
2712
  simple INSERT query pre-check.
1542
2738
 
1543
2739
 
1544
2740
/**
 
2741
  CREATE TABLE query pre-check.
 
2742
 
 
2743
  @param session                        Thread handler
 
2744
  @param tables         Global table list
 
2745
  @param create_table           Table which will be created
 
2746
 
 
2747
  @retval
 
2748
    false   OK
 
2749
  @retval
 
2750
    true   Error
 
2751
*/
 
2752
 
 
2753
bool create_table_precheck(Session *, TableList *,
 
2754
                           TableList *create_table)
 
2755
{
 
2756
  bool error= true;                                 // Error message is given
 
2757
 
 
2758
  if (create_table && (strcmp(create_table->db, "information_schema") == 0))
 
2759
  {
 
2760
    my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), "", "", INFORMATION_SCHEMA_NAME.c_str());
 
2761
    return(true);
 
2762
  }
 
2763
 
 
2764
  error= false;
 
2765
 
 
2766
  return(error);
 
2767
}
 
2768
 
 
2769
 
 
2770
/**
1545
2771
  negate given expression.
1546
2772
 
1547
2773
  @param session  thread handler
1650
2876
}
1651
2877
 
1652
2878
 
 
2879
/*
 
2880
  Check if path does not contain mysql data home directory
 
2881
  SYNOPSIS
 
2882
    test_if_data_home_dir()
 
2883
    dir                     directory
 
2884
    conv_home_dir           converted data home directory
 
2885
    home_dir_len            converted data home directory length
 
2886
 
 
2887
  RETURN VALUES
 
2888
    0   ok
 
2889
    1   error
 
2890
*/
 
2891
 
 
2892
bool test_if_data_home_dir(const char *dir)
 
2893
{
 
2894
  char path[FN_REFLEN], conv_path[FN_REFLEN];
 
2895
  uint32_t dir_len, home_dir_len= strlen(drizzle_unpacked_real_data_home);
 
2896
 
 
2897
  if (!dir)
 
2898
    return(0);
 
2899
 
 
2900
  (void) fn_format(path, dir, "", "",
 
2901
                   (MY_RETURN_REAL_PATH|MY_RESOLVE_SYMLINKS));
 
2902
  dir_len= unpack_dirname(conv_path, dir);
 
2903
 
 
2904
  if (home_dir_len < dir_len)
 
2905
  {
 
2906
    if (!my_strnncoll(character_set_filesystem,
 
2907
                      (const unsigned char*) conv_path, home_dir_len,
 
2908
                      (const unsigned char*) drizzle_unpacked_real_data_home,
 
2909
                      home_dir_len))
 
2910
      return(1);
 
2911
  }
 
2912
  return(0);
 
2913
}
 
2914
 
 
2915
 
 
2916
extern int DRIZZLEparse(void *session); // from sql_yacc.cc
 
2917
 
 
2918
 
1653
2919
/**
1654
2920
  This is a wrapper of DRIZZLEparse(). All the code should call parse_sql()
1655
2921
  instead of DRIZZLEparse().
1662
2928
    @retval true on parsing error.
1663
2929
*/
1664
2930
 
1665
 
static bool parse_sql(Session *session, Lex_input_stream *lip)
 
2931
bool parse_sql(Session *session, Lex_input_stream *lip)
1666
2932
{
1667
2933
  assert(session->m_lip == NULL);
1668
2934
 
1669
 
  DRIZZLE_QUERY_PARSE_START(session->getQueryString()->c_str());
1670
 
 
1671
2935
  /* Set Lex_input_stream. */
1672
2936
 
1673
2937
  session->m_lip= lip;
1684
2948
 
1685
2949
  session->m_lip= NULL;
1686
2950
 
1687
 
  DRIZZLE_QUERY_PARSE_DONE(mysql_parse_status || session->is_fatal_error);
1688
 
 
1689
2951
  /* That's it. */
1690
2952
 
1691
2953
  return mysql_parse_status || session->is_fatal_error;
1694
2956
/**
1695
2957
  @} (end of group Runtime_Environment)
1696
2958
*/
1697
 
 
1698
 
} /* namespace drizzled */