~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_parse.cc

Merge in security refactor.

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 */
 
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
15
 
16
16
#include "config.h"
17
17
 
18
18
#define DRIZZLE_LEX 1
19
19
 
20
 
#include "drizzled/item/num.h"
21
 
#include "drizzled/abort_exception.h"
22
20
#include <drizzled/my_hash.h>
23
21
#include <drizzled/error.h>
24
22
#include <drizzled/nested_join.h>
25
23
#include <drizzled/query_id.h>
26
 
#include "drizzled/transaction_services.h"
27
24
#include <drizzled/sql_parse.h>
28
25
#include <drizzled/data_home.h>
29
26
#include <drizzled/sql_base.h>
30
27
#include <drizzled/show.h>
31
28
#include <drizzled/db.h>
 
29
#include <drizzled/plugin/info_schema_table.h>
32
30
#include <drizzled/function/time/unix_timestamp.h>
33
31
#include <drizzled/function/get_system_var.h>
34
32
#include <drizzled/item/cmpfunc.h>
35
33
#include <drizzled/item/null.h>
36
34
#include <drizzled/session.h>
37
 
#include <drizzled/session/cache.h>
38
35
#include <drizzled/sql_load.h>
39
36
#include <drizzled/lock.h>
40
37
#include <drizzled/select_send.h>
42
39
#include <drizzled/statement.h>
43
40
#include <drizzled/statement/alter_table.h>
44
41
#include "drizzled/probes.h"
 
42
#include "drizzled/session_list.h"
45
43
#include "drizzled/global_charset_info.h"
 
44
#include "drizzled/transaction_services.h"
46
45
 
47
46
#include "drizzled/plugin/logging.h"
48
 
#include "drizzled/plugin/query_rewrite.h"
49
 
#include "drizzled/plugin/query_cache.h"
50
 
#include "drizzled/plugin/authorization.h"
 
47
#include "drizzled/plugin/info_schema_table.h"
51
48
#include "drizzled/optimizer/explain_plan.h"
52
49
#include "drizzled/pthread_globals.h"
53
 
#include "drizzled/plugin/event_observer.h"
54
 
#include "drizzled/visibility.h"
55
50
 
56
51
#include <limits.h>
57
52
 
58
53
#include <bitset>
59
54
#include <algorithm>
60
 
#include <boost/date_time.hpp>
 
55
 
61
56
#include "drizzled/internal/my_sys.h"
62
57
 
63
58
using namespace std;
70
65
/* Prototypes */
71
66
bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
72
67
static bool parse_sql(Session *session, Lex_input_stream *lip);
73
 
void parse(Session *session, const char *inBuf, uint32_t length);
 
68
static void mysql_parse(Session *session, const char *inBuf, uint32_t length,
 
69
                 const char ** found_semicolon);
74
70
 
75
71
/**
76
72
  @defgroup Runtime_Environment Runtime Environment
80
76
extern size_t my_thread_stack_size;
81
77
extern const CHARSET_INFO *character_set_filesystem;
82
78
 
83
 
namespace
84
 
{
85
 
 
86
 
static const std::string command_name[COM_END+1]={
87
 
  "Sleep",
88
 
  "Quit",
89
 
  "Init DB",
90
 
  "Query",
91
 
  "Shutdown",
92
 
  "Connect",
93
 
  "Ping",
94
 
  "Error"  // Last command number
 
79
const LEX_STRING command_name[COM_END+1]={
 
80
  { C_STRING_WITH_LEN("Sleep") },
 
81
  { C_STRING_WITH_LEN("Quit") },
 
82
  { C_STRING_WITH_LEN("Init DB") },
 
83
  { C_STRING_WITH_LEN("Query") },
 
84
  { C_STRING_WITH_LEN("Shutdown") },
 
85
  { C_STRING_WITH_LEN("Connect") },
 
86
  { C_STRING_WITH_LEN("Ping") },
 
87
  { C_STRING_WITH_LEN("Error") }  // Last command number
95
88
};
96
89
 
97
 
}
98
 
 
99
90
const char *xa_state_names[]={
100
91
  "NON-EXISTING", "ACTIVE", "IDLE", "PREPARED"
101
92
};
114
105
*/
115
106
bitset<CF_BIT_SIZE> sql_command_flags[SQLCOM_END+1];
116
107
 
117
 
const std::string &getCommandName(const enum_server_command& command)
118
 
{
119
 
  return command_name[command];
120
 
}
121
 
 
122
108
void init_update_queries(void)
123
109
{
124
110
  uint32_t x;
144
130
  sql_command_flags[SQLCOM_REPLACE]=        CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
145
131
  sql_command_flags[SQLCOM_REPLACE_SELECT]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
146
132
 
 
133
  sql_command_flags[SQLCOM_SHOW_STATUS]=      CF_STATUS_COMMAND;
 
134
  sql_command_flags[SQLCOM_SHOW_DATABASES]=   CF_STATUS_COMMAND;
 
135
  sql_command_flags[SQLCOM_SHOW_FIELDS]=      CF_STATUS_COMMAND;
 
136
  sql_command_flags[SQLCOM_SHOW_KEYS]=        CF_STATUS_COMMAND;
 
137
  sql_command_flags[SQLCOM_SHOW_VARIABLES]=   CF_STATUS_COMMAND;
147
138
  sql_command_flags[SQLCOM_SHOW_WARNS]= CF_STATUS_COMMAND;
148
139
  sql_command_flags[SQLCOM_SHOW_ERRORS]= CF_STATUS_COMMAND;
 
140
  sql_command_flags[SQLCOM_SHOW_PROCESSLIST]= CF_STATUS_COMMAND;
149
141
  sql_command_flags[SQLCOM_SHOW_CREATE_DB]=  CF_STATUS_COMMAND;
150
142
  sql_command_flags[SQLCOM_SHOW_CREATE]=  CF_STATUS_COMMAND;
151
143
 
 
144
   sql_command_flags[SQLCOM_SHOW_TABLES]=       (CF_STATUS_COMMAND |
 
145
                                               CF_SHOW_TABLE_COMMAND);
 
146
  sql_command_flags[SQLCOM_SHOW_TABLE_STATUS]= (CF_STATUS_COMMAND |
 
147
                                                CF_SHOW_TABLE_COMMAND);
152
148
  /*
153
149
    The following admin table operations are allowed
154
150
    on log tables.
183
179
  bool error= 0;
184
180
  Query_id &query_id= Query_id::get_query_id();
185
181
 
186
 
  DRIZZLE_COMMAND_START(session->thread_id, command);
 
182
  DRIZZLE_COMMAND_START(session->thread_id,
 
183
                        command);
187
184
 
188
185
  session->command= command;
189
186
  session->lex->sql_command= SQLCOM_END; /* to avoid confusing VIEW detectors */
196
193
    break;
197
194
  /* Increase id and count all other statements. */
198
195
  default:
199
 
    session->status_var.questions++;
 
196
    statistic_increment(session->status_var.questions, &LOCK_status);
200
197
    query_id.next();
201
198
  }
202
199
 
203
 
  /* @todo set session->lex->sql_command to SQLCOM_END here */
 
200
  /* TODO: set session->lex->sql_command to SQLCOM_END here */
204
201
 
205
202
  plugin::Logging::preDo(session);
206
 
  if (unlikely(plugin::EventObserver::beforeStatement(*session)))
207
 
  {
208
 
    // We should do something about an error...
209
 
  }
210
203
 
211
204
  session->server_status&=
212
205
           ~(SERVER_QUERY_NO_INDEX_USED | SERVER_QUERY_NO_GOOD_INDEX_USED);
213
206
  switch (command) {
214
207
  case COM_INIT_DB:
215
208
  {
216
 
    if (packet_length == 0)
217
 
    {
218
 
      my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
219
 
      break;
220
 
    }
221
 
 
222
 
    string tmp(packet, packet_length);
223
 
 
224
 
    identifier::Schema identifier(tmp);
225
 
 
226
 
    if (not change_db(session, identifier))
 
209
    LEX_STRING tmp;
 
210
    status_var_increment(session->status_var.com_stat[SQLCOM_CHANGE_DB]);
 
211
    tmp.str= packet;
 
212
    tmp.length= packet_length;
 
213
    if (!mysql_change_db(session, &tmp, false))
227
214
    {
228
215
      session->my_ok();
229
216
    }
231
218
  }
232
219
  case COM_QUERY:
233
220
  {
234
 
    if (not session->readAndStoreQuery(packet, packet_length))
 
221
    if (! session->readAndStoreQuery(packet, packet_length))
235
222
      break;                                    // fatal error is set
236
 
    DRIZZLE_QUERY_START(session->getQueryString()->c_str(),
 
223
    DRIZZLE_QUERY_START(session->query,
237
224
                        session->thread_id,
238
 
                        const_cast<const char *>(session->schema()->c_str()));
 
225
                        const_cast<const char *>(session->db.empty() ? "" : session->db.c_str()));
 
226
    const char* end_of_stmt= NULL;
239
227
 
240
 
    parse(session, session->getQueryString()->c_str(), session->getQueryString()->length());
 
228
    mysql_parse(session, session->query, session->query_length, &end_of_stmt);
241
229
 
242
230
    break;
243
231
  }
248
236
    break;
249
237
  case COM_SHUTDOWN:
250
238
  {
251
 
    session->status_var.com_other++;
 
239
    status_var_increment(session->status_var.com_other);
252
240
    session->my_eof();
253
241
    session->close_thread_tables();                     // Free before kill
254
242
    kill_drizzle();
256
244
    break;
257
245
  }
258
246
  case COM_PING:
259
 
    session->status_var.com_other++;
 
247
    status_var_increment(session->status_var.com_other);
260
248
    session->my_ok();                           // Tell client we are alive
261
249
    break;
262
250
  case COM_SLEEP:
270
258
  /* If commit fails, we should be able to reset the OK status. */
271
259
  session->main_da.can_overwrite_status= true;
272
260
  TransactionServices &transaction_services= TransactionServices::singleton();
273
 
  transaction_services.autocommitOrRollback(*session, session->is_error());
 
261
  transaction_services.ha_autocommit_or_rollback(session, session->is_error());
274
262
  session->main_da.can_overwrite_status= false;
275
263
 
276
264
  session->transaction.stmt.reset();
282
270
    if (! session->main_da.is_set())
283
271
      session->send_kill_message();
284
272
  }
285
 
  if (session->getKilled() == Session::KILL_QUERY || session->getKilled() == Session::KILL_BAD_DATA)
 
273
  if (session->killed == Session::KILL_QUERY || session->killed == Session::KILL_BAD_DATA)
286
274
  {
287
 
    session->setKilled(Session::NOT_KILLED);
288
 
    session->setAbort(false);
 
275
    session->killed= Session::NOT_KILLED;
 
276
    session->mysys_var->abort= 0;
289
277
  }
290
278
 
291
279
  /* Can not be true, but do not take chances in production. */
295
283
  {
296
284
  case Diagnostics_area::DA_ERROR:
297
285
    /* The query failed, send error to log and abort bootstrap. */
298
 
    session->getClient()->sendError(session->main_da.sql_errno(),
 
286
    session->client->sendError(session->main_da.sql_errno(),
299
287
                               session->main_da.message());
300
288
    break;
301
289
 
302
290
  case Diagnostics_area::DA_EOF:
303
 
    session->getClient()->sendEOF();
 
291
    session->client->sendEOF();
304
292
    break;
305
293
 
306
294
  case Diagnostics_area::DA_OK:
307
 
    session->getClient()->sendOK();
 
295
    session->client->sendOK();
308
296
    break;
309
297
 
310
298
  case Diagnostics_area::DA_DISABLED:
312
300
 
313
301
  case Diagnostics_area::DA_EMPTY:
314
302
  default:
315
 
    session->getClient()->sendOK();
 
303
    session->client->sendOK();
316
304
    break;
317
305
  }
318
306
 
323
311
  session->close_thread_tables();
324
312
 
325
313
  plugin::Logging::postDo(session);
326
 
  if (unlikely(plugin::EventObserver::afterStatement(*session)))
327
 
  {
328
 
    // We should do something about an error...
329
 
  }
330
314
 
331
315
  /* Store temp state for processlist */
332
316
  session->set_proc_info("cleaning up");
333
317
  session->command= COM_SLEEP;
334
 
  session->resetQueryString();
 
318
  memset(session->process_list_info, 0, PROCESS_LIST_WIDTH);
 
319
  session->query= 0;
 
320
  session->query_length= 0;
335
321
 
336
322
  session->set_proc_info(NULL);
337
 
  session->mem_root->free_root(MYF(memory::KEEP_PREALLOC));
 
323
  free_root(session->mem_root,MYF(memory::KEEP_PREALLOC));
338
324
 
339
325
  if (DRIZZLE_QUERY_DONE_ENABLED() || DRIZZLE_COMMAND_DONE_ENABLED())
340
326
  {
374
360
    1                 out of memory or SHOW commands are not allowed
375
361
                      in this version of the server.
376
362
*/
377
 
static bool _schema_select(Session *session, Select_Lex *sel,
378
 
                           const string& schema_table_name)
379
 
{
380
 
  LEX_STRING db, table;
381
 
  bitset<NUM_OF_TABLE_OPTIONS> table_options;
382
 
  /*
383
 
     We have to make non const db_name & table_name
384
 
     because of lower_case_table_names
385
 
  */
386
 
  session->make_lex_string(&db, "data_dictionary", sizeof("data_dictionary"), false);
387
 
  session->make_lex_string(&table, schema_table_name, false);
388
 
 
389
 
  if (! sel->add_table_to_list(session, new Table_ident(db, table),
390
 
                               NULL, table_options, TL_READ))
391
 
  {
392
 
    return true;
393
 
  }
394
 
  return false;
395
 
}
396
 
 
397
 
int prepare_new_schema_table(Session *session, LEX *lex,
398
 
                             const string& schema_table_name)
 
363
 
 
364
int prepare_schema_table(Session *session, LEX *lex, Table_ident *table_ident,
 
365
                         const string& schema_table_name)
399
366
{
400
367
  Select_Lex *schema_select_lex= NULL;
401
368
 
 
369
 
 
370
  if (schema_table_name.compare("TABLES") == 0 ||
 
371
      schema_table_name.compare("TABLE_NAMES") == 0)
 
372
  {
 
373
    LEX_STRING db;
 
374
    size_t dummy;
 
375
    if (lex->select_lex.db == NULL &&
 
376
        lex->copy_db_to(&lex->select_lex.db, &dummy))
 
377
    {
 
378
      return (1);
 
379
    }
 
380
    schema_select_lex= new Select_Lex();
 
381
    db.str= schema_select_lex->db= lex->select_lex.db;
 
382
    schema_select_lex->table_list.first= NULL;
 
383
    db.length= strlen(db.str);
 
384
 
 
385
    if (check_db_name(&db))
 
386
    {
 
387
      my_error(ER_WRONG_DB_NAME, MYF(0), db.str);
 
388
      return (1);
 
389
    }
 
390
  }
 
391
  else if (schema_table_name.compare("COLUMNS") == 0 ||
 
392
           schema_table_name.compare("STATISTICS") == 0)
 
393
  {
 
394
    assert(table_ident);
 
395
    TableList **query_tables_last= lex->query_tables_last;
 
396
    schema_select_lex= new Select_Lex();
 
397
    /* 'parent_lex' is used in init_query() so it must be before it. */
 
398
    schema_select_lex->parent_lex= lex;
 
399
    schema_select_lex->init_query();
 
400
    if (! schema_select_lex->add_table_to_list(session, table_ident, 0, 0, TL_READ))
 
401
    {
 
402
      return (1);
 
403
    }
 
404
    lex->query_tables_last= query_tables_last;
 
405
  }
 
406
 
402
407
  Select_Lex *select_lex= lex->current_select;
403
408
  assert(select_lex);
404
 
  if (_schema_select(session, select_lex, schema_table_name))
 
409
  if (make_schema_select(session, select_lex, schema_table_name))
405
410
  {
406
411
    return(1);
407
412
  }
442
447
    true        Error
443
448
*/
444
449
 
445
 
static int execute_command(Session *session)
 
450
static int
 
451
mysql_execute_command(Session *session)
446
452
{
447
453
  bool res= false;
448
454
  LEX  *lex= session->lex;
450
456
  Select_Lex *select_lex= &lex->select_lex;
451
457
  /* list of all tables in query */
452
458
  TableList *all_tables;
 
459
  /* A peek into the query string */
 
460
  size_t proc_info_len= session->query_length > PROCESS_LIST_WIDTH ?
 
461
                        PROCESS_LIST_WIDTH : session->query_length;
 
462
 
 
463
  memcpy(session->process_list_info, session->query, proc_info_len);
 
464
  session->process_list_info[proc_info_len]= '\0';
453
465
 
454
466
  /*
455
467
    In many cases first table of main Select_Lex have special meaning =>
486
498
    drizzle_reset_errors(session, 0);
487
499
  }
488
500
 
489
 
  assert(session->transaction.stmt.hasModifiedNonTransData() == false);
 
501
  status_var_increment(session->status_var.com_stat[lex->sql_command]);
490
502
 
491
 
  if (! (session->server_status & SERVER_STATUS_AUTOCOMMIT)
492
 
      && ! session->inTransaction()
493
 
      && lex->statement->isTransactional())
494
 
  {
495
 
    if (session->startTransaction() == false)
496
 
    {
497
 
      my_error(drizzled::ER_UNKNOWN_ERROR, MYF(0));
498
 
      return true;
499
 
    }
500
 
  }
 
503
  assert(session->transaction.stmt.modified_non_trans_table == false);
501
504
 
502
505
  /* now we are ready to execute the statement */
503
506
  res= lex->statement->execute();
 
507
 
504
508
  session->set_proc_info("query end");
 
509
 
505
510
  /*
506
511
    The return value for ROW_COUNT() is "implementation dependent" if the
507
512
    statement is not DELETE, INSERT or UPDATE, but -1 is what JDBC and ODBC
515
520
 
516
521
  return (res || session->is_error());
517
522
}
 
523
 
518
524
bool execute_sqlcom_select(Session *session, TableList *all_tables)
519
525
{
520
526
  LEX   *lex= session->lex;
527
533
      param->select_limit=
528
534
        new Item_int((uint64_t) session->variables.select_limit);
529
535
  }
530
 
 
531
 
  if (all_tables
532
 
      && ! (session->server_status & SERVER_STATUS_AUTOCOMMIT)
533
 
      && ! session->inTransaction()
534
 
      && ! lex->statement->isShow())
535
 
  {
536
 
    if (session->startTransaction() == false)
537
 
    {
538
 
      my_error(drizzled::ER_UNKNOWN_ERROR, MYF(0));
539
 
      return true;
540
 
    }
541
 
  }
542
 
 
543
 
  if (not (res= session->openTablesLock(all_tables)))
 
536
  if (!(res= session->openTablesLock(all_tables)))
544
537
  {
545
538
    if (lex->describe)
546
539
    {
575
568
    {
576
569
      if (!result && !(result= new select_send()))
577
570
        return true;
578
 
 
579
 
      /* Init the Query Cache plugin */
580
 
      plugin::QueryCache::prepareResultset(session); 
581
571
      res= handle_select(session, lex, result, 0);
582
 
      /* Send the Resultset to the cache */
583
 
      plugin::QueryCache::setResultset(session); 
584
 
 
585
572
      if (result != lex->result)
586
573
        delete result;
587
574
    }
624
611
 
625
612
 
626
613
void
627
 
init_select(LEX *lex)
 
614
mysql_init_select(LEX *lex)
628
615
{
629
616
  Select_Lex *select_lex= lex->current_select;
630
617
  select_lex->init_select();
638
625
 
639
626
 
640
627
bool
641
 
new_select(LEX *lex, bool move_down)
 
628
mysql_new_select(LEX *lex, bool move_down)
642
629
{
643
630
  Select_Lex *select_lex;
644
631
  Session *session= lex->session;
645
632
 
646
633
  if (!(select_lex= new (session->mem_root) Select_Lex()))
647
 
    return true;
648
 
 
 
634
    return(1);
649
635
  select_lex->select_number= ++session->select_number;
650
636
  select_lex->parent_lex= lex; /* Used in init_query. */
651
637
  select_lex->init_query();
652
638
  select_lex->init_select();
653
639
  lex->nest_level++;
654
 
 
655
640
  if (lex->nest_level > (int) MAX_SELECT_NESTING)
656
641
  {
657
642
    my_error(ER_TOO_HIGH_LEVEL_OF_NESTING_FOR_SELECT,MYF(0),MAX_SELECT_NESTING);
658
643
    return(1);
659
644
  }
660
 
 
661
645
  select_lex->nest_level= lex->nest_level;
662
646
  if (move_down)
663
647
  {
685
669
    if (lex->current_select->order_list.first && !lex->current_select->braces)
686
670
    {
687
671
      my_error(ER_WRONG_USAGE, MYF(0), "UNION", "order_st BY");
688
 
      return true;
 
672
      return(1);
689
673
    }
690
 
 
691
674
    select_lex->include_neighbour(lex->current_select);
692
675
    Select_Lex_Unit *unit= select_lex->master_unit();
693
 
 
694
 
    if (not unit->fake_select_lex && unit->add_fake_select_lex(lex->session))
695
 
      return true;
696
 
 
 
676
    if (!unit->fake_select_lex && unit->add_fake_select_lex(lex->session))
 
677
      return(1);
697
678
    select_lex->context.outer_context=
698
679
                unit->first_select()->context.outer_context;
699
680
  }
706
687
    list
707
688
  */
708
689
  select_lex->context.resolve_in_select_list= true;
709
 
 
710
 
  return false;
 
690
  return(0);
711
691
}
712
692
 
713
693
/**
720
700
  @param var_name               Variable name
721
701
*/
722
702
 
723
 
void create_select_for_variable(Session *session, const char *var_name)
 
703
void create_select_for_variable(const char *var_name)
724
704
{
 
705
  Session *session;
725
706
  LEX *lex;
726
707
  LEX_STRING tmp, null_lex_string;
727
708
  Item *var;
728
709
  char buff[MAX_SYS_VAR_LENGTH*2+4+8];
729
710
  char *end= buff;
730
711
 
 
712
  session= current_session;
731
713
  lex= session->lex;
732
 
  init_select(lex);
 
714
  mysql_init_select(lex);
733
715
  lex->sql_command= SQLCOM_SELECT;
734
716
  tmp.str= (char*) var_name;
735
717
  tmp.length=strlen(var_name);
740
722
  */
741
723
  if ((var= get_system_var(session, OPT_SESSION, tmp, null_lex_string)))
742
724
  {
743
 
    end+= snprintf(buff, sizeof(buff), "@@session.%s", var_name);
 
725
    end+= sprintf(buff, "@@session.%s", var_name);
744
726
    var->set_name(buff, end-buff, system_charset_info);
745
727
    session->add_item_to_list(var);
746
728
  }
 
729
  return;
747
730
}
748
731
 
749
732
 
753
736
  @param       session     Current thread
754
737
  @param       inBuf   Begining of the query text
755
738
  @param       length  Length of the query text
 
739
  @param[out]  found_semicolon For multi queries, position of the character of
 
740
                               the next query in the query text.
756
741
*/
757
742
 
758
 
void parse(Session *session, const char *inBuf, uint32_t length)
 
743
static void mysql_parse(Session *session, const char *inBuf, uint32_t length,
 
744
                 const char ** found_semicolon)
759
745
{
760
 
  session->lex->start(session);
761
 
 
 
746
  /*
 
747
    Warning.
 
748
    The purpose of query_cache_send_result_to_client() is to lookup the
 
749
    query in the query cache first, to avoid parsing and executing it.
 
750
    So, the natural implementation would be to:
 
751
    - first, call query_cache_send_result_to_client,
 
752
    - second, if caching failed, initialise the lexical and syntactic parser.
 
753
    The problem is that the query cache depends on a clean initialization
 
754
    of (among others) lex->safe_to_cache_query and session->server_status,
 
755
    which are reset respectively in
 
756
    - lex_start()
 
757
    - mysql_reset_session_for_next_command()
 
758
    So, initializing the lexical analyser *before* using the query cache
 
759
    is required for the cache to work properly.
 
760
    FIXME: cleanup the dependencies in the code to simplify this.
 
761
  */
 
762
  lex_start(session);
762
763
  session->reset_for_next_command();
763
 
  /* Check if the Query is Cached if and return true if yes
764
 
   * TODO the plugin has to make sure that the query is cacheble
765
 
   * by setting the query_safe_cache param to TRUE
766
 
   */
767
 
  bool res= true;
768
 
  if (plugin::QueryCache::isCached(session))
769
 
  {
770
 
    res= plugin::QueryCache::sendCachedResultset(session);
771
 
  }
772
 
  if (not res)
773
 
  {
774
 
    return;
775
 
  }
776
 
  LEX *lex= session->lex;
777
 
  Lex_input_stream lip(session, inBuf, length);
778
 
  bool err= parse_sql(session, &lip);
779
 
  if (!err)
780
 
  {
 
764
 
 
765
  {
 
766
    LEX *lex= session->lex;
 
767
 
 
768
    Lex_input_stream lip(session, inBuf, length);
 
769
 
 
770
    bool err= parse_sql(session, &lip);
 
771
    *found_semicolon= lip.found_semicolon;
 
772
 
 
773
    if (!err)
781
774
    {
782
 
      if (not session->is_error())
783
775
      {
784
 
        DRIZZLE_QUERY_EXEC_START(session->getQueryString()->c_str(),
785
 
                                 session->thread_id,
786
 
                                 const_cast<const char *>(session->schema()->c_str()));
787
 
        // Implement Views here --Brian
788
 
        /* Actually execute the query */
789
 
        try 
790
 
        {
791
 
          execute_command(session);
792
 
        }
793
 
        catch (...)
794
 
        {
795
 
          // Just try to catch any random failures that could have come
796
 
          // during execution.
797
 
          DRIZZLE_ABORT;
798
 
        }
799
 
        DRIZZLE_QUERY_EXEC_DONE(0);
 
776
        if (! session->is_error())
 
777
        {
 
778
          /*
 
779
            Binlog logs a string starting from session->query and having length
 
780
            session->query_length; so we set session->query_length correctly (to not
 
781
            log several statements in one event, when we executed only first).
 
782
            We set it to not see the ';' (otherwise it would get into binlog
 
783
            and Query_log_event::print() would give ';;' output).
 
784
            This also helps display only the current query in SHOW
 
785
            PROCESSLIST.
 
786
            Note that we don't need LOCK_thread_count to modify query_length.
 
787
          */
 
788
          if (*found_semicolon &&
 
789
              (session->query_length= (ulong)(*found_semicolon - session->query)))
 
790
            session->query_length--;
 
791
          DRIZZLE_QUERY_EXEC_START(session->query,
 
792
                                   session->thread_id,
 
793
                                   const_cast<const char *>(session->db.empty() ? "" : session->db.c_str()));
 
794
          /* Actually execute the query */
 
795
          mysql_execute_command(session);
 
796
          DRIZZLE_QUERY_EXEC_DONE(0);
 
797
        }
800
798
      }
801
799
    }
802
 
  }
803
 
  else
804
 
  {
805
 
    assert(session->is_error());
806
 
  }
807
 
  lex->unit.cleanup();
808
 
  session->set_proc_info("freeing items");
809
 
  session->end_statement();
810
 
  session->cleanup_after_query();
811
 
  session->set_end_timer();
 
800
    else
 
801
    {
 
802
      assert(session->is_error());
 
803
    }
 
804
    lex->unit.cleanup();
 
805
    session->set_proc_info("freeing items");
 
806
    session->end_statement();
 
807
    session->cleanup_after_query();
 
808
  }
 
809
 
 
810
  return;
812
811
}
813
812
 
814
813
 
868
867
    */
869
868
    if (default_value->type() == Item::FUNC_ITEM &&
870
869
        !(((Item_func*)default_value)->functype() == Item_func::NOW_FUNC &&
871
 
         (type == DRIZZLE_TYPE_TIMESTAMP or type == DRIZZLE_TYPE_MICROTIME)))
 
870
         type == DRIZZLE_TYPE_TIMESTAMP))
872
871
    {
873
872
      my_error(ER_INVALID_DEFAULT, MYF(0), field_name->str);
874
873
      return true;
876
875
    else if (default_value->type() == Item::NULL_ITEM)
877
876
    {
878
877
      default_value= 0;
879
 
      if ((type_modifier & (NOT_NULL_FLAG | AUTO_INCREMENT_FLAG)) == NOT_NULL_FLAG)
 
878
      if ((type_modifier & (NOT_NULL_FLAG | AUTO_INCREMENT_FLAG)) ==
 
879
          NOT_NULL_FLAG)
880
880
      {
881
881
        my_error(ER_INVALID_DEFAULT, MYF(0), field_name->str);
882
882
        return true;
889
889
    }
890
890
  }
891
891
 
892
 
  if (on_update_value && (type != DRIZZLE_TYPE_TIMESTAMP and type != DRIZZLE_TYPE_MICROTIME))
 
892
  if (on_update_value && type != DRIZZLE_TYPE_TIMESTAMP)
893
893
  {
894
894
    my_error(ER_INVALID_ON_UPDATE, MYF(0), field_name->str);
895
895
    return true;
908
908
}
909
909
 
910
910
 
 
911
/** Store position for column in ALTER TABLE .. ADD column. */
 
912
 
 
913
void store_position_for_column(const char *name)
 
914
{
 
915
  current_session->lex->last_field->after=const_cast<char*> (name);
 
916
}
 
917
 
911
918
/**
912
919
  Add a table to list of used tables.
913
920
 
928
935
*/
929
936
 
930
937
TableList *Select_Lex::add_table_to_list(Session *session,
931
 
                                         Table_ident *table,
932
 
                                         LEX_STRING *alias,
933
 
                                         const bitset<NUM_OF_TABLE_OPTIONS>& table_options,
934
 
                                         thr_lock_type lock_type,
935
 
                                         List<Index_hint> *index_hints_arg,
936
 
                                         LEX_STRING *option)
 
938
                                             Table_ident *table,
 
939
                                             LEX_STRING *alias,
 
940
                                             uint32_t table_options,
 
941
                                             thr_lock_type lock_type,
 
942
                                             List<Index_hint> *index_hints_arg,
 
943
                                             LEX_STRING *option)
937
944
{
938
 
  TableList *ptr;
 
945
  register TableList *ptr;
939
946
  TableList *previous_table_ref; /* The table preceding the current one. */
940
947
  char *alias_str;
941
948
  LEX *lex= session->lex;
943
950
  if (!table)
944
951
    return NULL;                                // End of memory
945
952
  alias_str= alias ? alias->str : table->table.str;
946
 
  if (! table_options.test(TL_OPTION_ALIAS) &&
 
953
  if (!test(table_options & TL_OPTION_ALIAS) &&
947
954
      check_table_name(table->table.str, table->table.length))
948
955
  {
949
956
    my_error(ER_WRONG_TABLE_NAME, MYF(0), table->table.str);
950
957
    return NULL;
951
958
  }
952
959
 
953
 
  if (table->is_derived_table() == false && table->db.str)
 
960
  if (table->is_derived_table() == false && table->db.str &&
 
961
      check_db_name(&table->db))
954
962
  {
955
 
    my_casedn_str(files_charset_info, table->db.str);
956
 
 
957
 
    identifier::Schema schema_identifier(string(table->db.str));
958
 
    if (not check_db_name(session, schema_identifier))
959
 
    {
960
 
 
961
 
      my_error(ER_WRONG_DB_NAME, MYF(0), table->db.str);
962
 
      return NULL;
963
 
    }
 
963
    my_error(ER_WRONG_DB_NAME, MYF(0), table->db.str);
 
964
    return NULL;
964
965
  }
965
966
 
966
967
  if (!alias)                                   /* Alias is case sensitive */
971
972
                 ER(ER_DERIVED_MUST_HAVE_ALIAS), MYF(0));
972
973
      return NULL;
973
974
    }
974
 
    if (!(alias_str= (char*) session->getMemRoot()->duplicate(alias_str,table->table.length+1)))
 
975
    if (!(alias_str= (char*) session->memdup(alias_str,table->table.length+1)))
975
976
      return NULL;
976
977
  }
977
978
  if (!(ptr = (TableList *) session->calloc(sizeof(TableList))))
978
979
    return NULL;
979
 
 
980
980
  if (table->db.str)
981
981
  {
982
 
    ptr->setIsFqtn(true);
983
 
    ptr->setSchemaName(table->db.str);
 
982
    ptr->is_fqtn= true;
 
983
    ptr->db= table->db.str;
984
984
    ptr->db_length= table->db.length;
985
985
  }
986
 
  else if (lex->copy_db_to(ptr->getSchemaNamePtr(), &ptr->db_length))
 
986
  else if (lex->copy_db_to(&ptr->db, &ptr->db_length))
987
987
    return NULL;
988
988
  else
989
 
    ptr->setIsFqtn(false);
 
989
    ptr->is_fqtn= false;
990
990
 
991
991
  ptr->alias= alias_str;
992
 
  ptr->setIsAlias(alias ? true : false);
993
 
  ptr->setTableName(table->table.str);
 
992
  ptr->is_alias= alias ? true : false;
 
993
  if (table->table.length)
 
994
    table->table.length= my_casedn_str(files_charset_info, table->table.str);
 
995
  ptr->table_name=table->table.str;
994
996
  ptr->table_name_length=table->table.length;
995
997
  ptr->lock_type=   lock_type;
996
 
  ptr->force_index= table_options.test(TL_OPTION_FORCE_INDEX);
997
 
  ptr->ignore_leaves= table_options.test(TL_OPTION_IGNORE_LEAVES);
 
998
  ptr->updating=    test(table_options & TL_OPTION_UPDATING);
 
999
  ptr->force_index= test(table_options & TL_OPTION_FORCE_INDEX);
 
1000
  ptr->ignore_leaves= test(table_options & TL_OPTION_IGNORE_LEAVES);
998
1001
  ptr->derived=     table->sel;
 
1002
  if (!ptr->derived && !my_strcasecmp(system_charset_info, ptr->db,
 
1003
                                      INFORMATION_SCHEMA_NAME.c_str()))
 
1004
  {
 
1005
    plugin::InfoSchemaTable *schema_table= plugin::InfoSchemaTable::getTable(ptr->table_name);
 
1006
    if (!schema_table ||
 
1007
        (schema_table->isHidden() &&
 
1008
         ((sql_command_flags[lex->sql_command].test(CF_BIT_STATUS_COMMAND)) == 0 ||
 
1009
          /*
 
1010
            this check is used for show columns|keys from I_S hidden table
 
1011
          */
 
1012
          lex->sql_command == SQLCOM_SHOW_FIELDS ||
 
1013
          lex->sql_command == SQLCOM_SHOW_KEYS)))
 
1014
    {
 
1015
      my_error(ER_UNKNOWN_TABLE, MYF(0),
 
1016
               ptr->table_name, INFORMATION_SCHEMA_NAME.c_str());
 
1017
      return NULL;
 
1018
    }
 
1019
  }
999
1020
  ptr->select_lex=  lex->current_select;
1000
1021
  ptr->index_hints= index_hints_arg;
1001
1022
  ptr->option= option ? option->str : 0;
1007
1028
         tables ;
1008
1029
         tables=tables->next_local)
1009
1030
    {
1010
 
      if (not my_strcasecmp(table_alias_charset, alias_str, tables->alias) &&
1011
 
          not my_strcasecmp(system_charset_info, ptr->getSchemaName(), tables->getSchemaName()))
 
1031
      if (!my_strcasecmp(table_alias_charset, alias_str, tables->alias) &&
 
1032
          !strcmp(ptr->db, tables->db))
1012
1033
      {
1013
1034
        my_error(ER_NONUNIQ_TABLE, MYF(0), alias_str);
1014
1035
        return NULL;
1072
1093
bool Select_Lex::init_nested_join(Session *session)
1073
1094
{
1074
1095
  TableList *ptr;
1075
 
  NestedJoin *nested_join;
 
1096
  nested_join_st *nested_join;
1076
1097
 
1077
1098
  if (!(ptr= (TableList*) session->calloc(ALIGN_SIZE(sizeof(TableList))+
1078
 
                                       sizeof(NestedJoin))))
 
1099
                                       sizeof(nested_join_st))))
1079
1100
    return true;
1080
 
  ptr->setNestedJoin(((NestedJoin*) ((unsigned char*) ptr + ALIGN_SIZE(sizeof(TableList)))));
1081
 
  nested_join= ptr->getNestedJoin();
 
1101
  nested_join= ptr->nested_join=
 
1102
    ((nested_join_st*) ((unsigned char*) ptr + ALIGN_SIZE(sizeof(TableList))));
 
1103
 
1082
1104
  join_list->push_front(ptr);
1083
 
  ptr->setEmbedding(embedding);
1084
 
  ptr->setJoinList(join_list);
 
1105
  ptr->embedding= embedding;
 
1106
  ptr->join_list= join_list;
1085
1107
  ptr->alias= (char*) "(nested_join)";
1086
1108
  embedding= ptr;
1087
1109
  join_list= &nested_join->join_list;
1107
1129
TableList *Select_Lex::end_nested_join(Session *)
1108
1130
{
1109
1131
  TableList *ptr;
1110
 
  NestedJoin *nested_join;
 
1132
  nested_join_st *nested_join;
1111
1133
 
1112
1134
  assert(embedding);
1113
1135
  ptr= embedding;
1114
 
  join_list= ptr->getJoinList();
1115
 
  embedding= ptr->getEmbedding();
1116
 
  nested_join= ptr->getNestedJoin();
 
1136
  join_list= ptr->join_list;
 
1137
  embedding= ptr->embedding;
 
1138
  nested_join= ptr->nested_join;
1117
1139
  if (nested_join->join_list.elements == 1)
1118
1140
  {
1119
1141
    TableList *embedded= nested_join->join_list.head();
1120
1142
    join_list->pop();
1121
 
    embedded->setJoinList(join_list);
1122
 
    embedded->setEmbedding(embedding);
 
1143
    embedded->join_list= join_list;
 
1144
    embedded->embedding= embedding;
1123
1145
    join_list->push_front(embedded);
1124
1146
    ptr= embedded;
1125
1147
  }
1148
1170
TableList *Select_Lex::nest_last_join(Session *session)
1149
1171
{
1150
1172
  TableList *ptr;
1151
 
  NestedJoin *nested_join;
 
1173
  nested_join_st *nested_join;
1152
1174
  List<TableList> *embedded_list;
1153
1175
 
1154
1176
  if (!(ptr= (TableList*) session->calloc(ALIGN_SIZE(sizeof(TableList))+
1155
 
                                          sizeof(NestedJoin))))
 
1177
                                       sizeof(nested_join_st))))
1156
1178
    return NULL;
1157
 
  ptr->setNestedJoin(((NestedJoin*) ((unsigned char*) ptr + ALIGN_SIZE(sizeof(TableList)))));
1158
 
  nested_join= ptr->getNestedJoin();
1159
 
  ptr->setEmbedding(embedding);
1160
 
  ptr->setJoinList(join_list);
 
1179
  nested_join= ptr->nested_join=
 
1180
    ((nested_join_st*) ((unsigned char*) ptr + ALIGN_SIZE(sizeof(TableList))));
 
1181
 
 
1182
  ptr->embedding= embedding;
 
1183
  ptr->join_list= join_list;
1161
1184
  ptr->alias= (char*) "(nest_last_join)";
1162
1185
  embedded_list= &nested_join->join_list;
1163
1186
  embedded_list->empty();
1165
1188
  for (uint32_t i=0; i < 2; i++)
1166
1189
  {
1167
1190
    TableList *table= join_list->pop();
1168
 
    table->setJoinList(embedded_list);
1169
 
    table->setEmbedding(ptr);
 
1191
    table->join_list= embedded_list;
 
1192
    table->embedding= ptr;
1170
1193
    embedded_list->push_back(table);
1171
1194
    if (table->natural_join)
1172
1195
    {
1202
1225
void Select_Lex::add_joined_table(TableList *table)
1203
1226
{
1204
1227
  join_list->push_front(table);
1205
 
  table->setJoinList(join_list);
1206
 
  table->setEmbedding(embedding);
 
1228
  table->join_list= join_list;
 
1229
  table->embedding= embedding;
1207
1230
}
1208
1231
 
1209
1232
 
1263
1286
 
1264
1287
void Select_Lex::set_lock_for_tables(thr_lock_type lock_type)
1265
1288
{
 
1289
  bool for_update= lock_type >= TL_READ_NO_INSERT;
 
1290
 
1266
1291
  for (TableList *tables= (TableList*) table_list.first;
1267
1292
       tables;
1268
1293
       tables= tables->next_local)
1269
1294
  {
1270
1295
    tables->lock_type= lock_type;
 
1296
    tables->updating=  for_update;
1271
1297
  }
 
1298
  return;
1272
1299
}
1273
1300
 
1274
1301
 
1446
1473
 
1447
1474
 
1448
1475
/**
 
1476
  kill on thread.
 
1477
 
 
1478
  @param session                        Thread class
 
1479
  @param id                     Thread id
 
1480
  @param only_kill_query        Should it kill the query or the connection
 
1481
 
 
1482
  @note
 
1483
    This is written such that we have a short lock on LOCK_thread_count
 
1484
*/
 
1485
 
 
1486
static unsigned int
 
1487
kill_one_thread(Session *, ulong id, bool only_kill_query)
 
1488
{
 
1489
  Session *tmp= NULL;
 
1490
  uint32_t error=ER_NO_SUCH_THREAD;
 
1491
  pthread_mutex_lock(&LOCK_thread_count); // For unlink from list
 
1492
  
 
1493
  for( vector<Session*>::iterator it= getSessionList().begin(); it != getSessionList().end(); ++it )
 
1494
  {
 
1495
    if ((*it)->thread_id == id)
 
1496
    {
 
1497
      tmp= *it;
 
1498
      pthread_mutex_lock(&tmp->LOCK_delete);    // Lock from delete
 
1499
      break;
 
1500
    }
 
1501
  }
 
1502
  pthread_mutex_unlock(&LOCK_thread_count);
 
1503
  if (tmp)
 
1504
  {
 
1505
    tmp->awake(only_kill_query ? Session::KILL_QUERY : Session::KILL_CONNECTION);
 
1506
    error=0;
 
1507
    pthread_mutex_unlock(&tmp->LOCK_delete);
 
1508
  }
 
1509
  return(error);
 
1510
}
 
1511
 
 
1512
 
 
1513
/*
 
1514
  kills a thread and sends response
 
1515
 
 
1516
  SYNOPSIS
 
1517
    sql_kill()
 
1518
    session                     Thread class
 
1519
    id                  Thread id
 
1520
    only_kill_query     Should it kill the query or the connection
 
1521
*/
 
1522
 
 
1523
void sql_kill(Session *session, ulong id, bool only_kill_query)
 
1524
{
 
1525
  uint32_t error;
 
1526
  if (!(error= kill_one_thread(session, id, only_kill_query)))
 
1527
    session->my_ok();
 
1528
  else
 
1529
    my_error(error, MYF(0), id);
 
1530
}
 
1531
 
 
1532
 
 
1533
/**
1449
1534
  Check if the select is a simple select (not an union).
1450
1535
 
1451
1536
  @retval
1454
1539
    1   error   ; In this case the error messege is sent to the client
1455
1540
*/
1456
1541
 
1457
 
bool check_simple_select(Session::pointer session)
 
1542
bool check_simple_select()
1458
1543
{
 
1544
  Session *session= current_session;
1459
1545
  LEX *lex= session->lex;
1460
1546
  if (lex->current_select != &lex->select_lex)
1461
1547
  {
1572
1658
 
1573
1659
 
1574
1660
/**
 
1661
  CREATE TABLE query pre-check.
 
1662
 
 
1663
  @param session                        Thread handler
 
1664
  @param tables         Global table list
 
1665
  @param create_table           Table which will be created
 
1666
 
 
1667
  @retval
 
1668
    false   OK
 
1669
  @retval
 
1670
    true   Error
 
1671
*/
 
1672
 
 
1673
bool create_table_precheck(TableIdentifier &identifier)
 
1674
{
 
1675
  if (strcmp(identifier.getDBName(), "information_schema") == 0)
 
1676
  {
 
1677
    my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), "", "", INFORMATION_SCHEMA_NAME.c_str());
 
1678
    return true;
 
1679
  }
 
1680
 
 
1681
  return false;
 
1682
}
 
1683
 
 
1684
 
 
1685
/**
1575
1686
  negate given expression.
1576
1687
 
1577
1688
  @param session  thread handler
1638
1749
}
1639
1750
 
1640
1751
 
1641
 
bool check_identifier_name(LEX_STRING *str, error_t err_code,
 
1752
bool check_identifier_name(LEX_STRING *str, uint32_t err_code,
1642
1753
                           uint32_t max_char_length,
1643
1754
                           const char *param_for_err_msg)
1644
1755
{
1664
1775
 
1665
1776
  switch (err_code)
1666
1777
  {
1667
 
  case EE_OK:
 
1778
  case 0:
1668
1779
    break;
1669
1780
  case ER_WRONG_STRING_LENGTH:
1670
1781
    my_error(err_code, MYF(0), str->str, param_for_err_msg, max_char_length);
1676
1787
    assert(0);
1677
1788
    break;
1678
1789
  }
1679
 
 
1680
1790
  return true;
1681
1791
}
1682
1792
 
1697
1807
{
1698
1808
  assert(session->m_lip == NULL);
1699
1809
 
1700
 
  DRIZZLE_QUERY_PARSE_START(session->getQueryString()->c_str());
 
1810
  DRIZZLE_QUERY_PARSE_START(session->query);
1701
1811
 
1702
1812
  /* Set Lex_input_stream. */
1703
1813
 
1705
1815
 
1706
1816
  /* Parse the query. */
1707
1817
 
1708
 
  bool parse_status= DRIZZLEparse(session) != 0;
 
1818
  bool mysql_parse_status= DRIZZLEparse(session) != 0;
1709
1819
 
1710
1820
  /* Check that if DRIZZLEparse() failed, session->is_error() is set. */
1711
1821
 
1712
 
  assert(!parse_status || session->is_error());
 
1822
  assert(!mysql_parse_status || session->is_error());
1713
1823
 
1714
1824
  /* Reset Lex_input_stream. */
1715
1825
 
1716
1826
  session->m_lip= NULL;
1717
1827
 
1718
 
  DRIZZLE_QUERY_PARSE_DONE(parse_status || session->is_fatal_error);
 
1828
  DRIZZLE_QUERY_PARSE_DONE(mysql_parse_status || session->is_fatal_error);
1719
1829
 
1720
1830
  /* That's it. */
1721
1831
 
1722
 
  return parse_status || session->is_fatal_error;
 
1832
  return mysql_parse_status || session->is_fatal_error;
1723
1833
}
1724
1834
 
1725
1835
/**