~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_parse.cc

Renamed namespace slot to namespace service.

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/db.h>
21
20
#include <drizzled/error.h>
22
21
#include <drizzled/nested_join.h>
23
22
#include <drizzled/query_id.h>
24
 
#include "drizzled/transaction_services.h"
25
23
#include <drizzled/sql_parse.h>
26
24
#include <drizzled/data_home.h>
27
25
#include <drizzled/sql_base.h>
28
26
#include <drizzled/show.h>
29
 
#include <drizzled/db.h>
 
27
#include <drizzled/plugin/info_schema_table.h>
30
28
#include <drizzled/function/time/unix_timestamp.h>
31
29
#include <drizzled/function/get_system_var.h>
32
30
#include <drizzled/item/cmpfunc.h>
37
35
#include <drizzled/select_send.h>
38
36
#include <drizzled/plugin/client.h>
39
37
#include <drizzled/statement.h>
40
 
#include <drizzled/statement/alter_table.h>
41
38
#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
 
 
40
#include "drizzled/plugin/registry.h"
54
41
 
55
42
#include <bitset>
56
43
#include <algorithm>
57
 
#include <boost/date_time.hpp>
58
 
#include "drizzled/internal/my_sys.h"
59
44
 
 
45
using namespace drizzled;
60
46
using namespace std;
61
47
 
62
 
extern int DRIZZLEparse(void *session); // from sql_yacc.cc
63
 
 
64
 
namespace drizzled
65
 
{
66
 
 
67
48
/* Prototypes */
68
49
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
50
 
72
51
/**
73
52
  @defgroup Runtime_Environment Runtime Environment
76
55
 
77
56
extern size_t my_thread_stack_size;
78
57
extern const CHARSET_INFO *character_set_filesystem;
 
58
const char *any_db="*any*";     // Special symbol for check_access
79
59
 
80
60
const LEX_STRING command_name[COM_END+1]={
81
61
  { C_STRING_WITH_LEN("Sleep") },
131
111
  sql_command_flags[SQLCOM_REPLACE]=        CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
132
112
  sql_command_flags[SQLCOM_REPLACE_SELECT]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
133
113
 
 
114
  sql_command_flags[SQLCOM_SHOW_STATUS]=      CF_STATUS_COMMAND;
 
115
  sql_command_flags[SQLCOM_SHOW_DATABASES]=   CF_STATUS_COMMAND;
 
116
  sql_command_flags[SQLCOM_SHOW_OPEN_TABLES]= CF_STATUS_COMMAND;
 
117
  sql_command_flags[SQLCOM_SHOW_FIELDS]=      CF_STATUS_COMMAND;
 
118
  sql_command_flags[SQLCOM_SHOW_KEYS]=        CF_STATUS_COMMAND;
 
119
  sql_command_flags[SQLCOM_SHOW_VARIABLES]=   CF_STATUS_COMMAND;
134
120
  sql_command_flags[SQLCOM_SHOW_WARNS]= CF_STATUS_COMMAND;
135
121
  sql_command_flags[SQLCOM_SHOW_ERRORS]= CF_STATUS_COMMAND;
 
122
  sql_command_flags[SQLCOM_SHOW_ENGINE_STATUS]= CF_STATUS_COMMAND;
 
123
  sql_command_flags[SQLCOM_SHOW_PROCESSLIST]= CF_STATUS_COMMAND;
136
124
  sql_command_flags[SQLCOM_SHOW_CREATE_DB]=  CF_STATUS_COMMAND;
137
125
  sql_command_flags[SQLCOM_SHOW_CREATE]=  CF_STATUS_COMMAND;
138
126
 
 
127
   sql_command_flags[SQLCOM_SHOW_TABLES]=       (CF_STATUS_COMMAND |
 
128
                                               CF_SHOW_TABLE_COMMAND);
 
129
  sql_command_flags[SQLCOM_SHOW_TABLE_STATUS]= (CF_STATUS_COMMAND |
 
130
                                                CF_SHOW_TABLE_COMMAND);
139
131
  /*
140
132
    The following admin table operations are allowed
141
133
    on log tables.
142
134
  */
 
135
  sql_command_flags[SQLCOM_OPTIMIZE]=         CF_WRITE_LOGS_COMMAND;
143
136
  sql_command_flags[SQLCOM_ANALYZE]=          CF_WRITE_LOGS_COMMAND;
144
137
}
145
138
 
 
139
 
 
140
bool is_update_query(enum enum_sql_command command)
 
141
{
 
142
  assert(command >= 0 && command <= SQLCOM_END);
 
143
  return (sql_command_flags[command].test(CF_BIT_CHANGES_DATA));
 
144
}
 
145
 
146
146
/**
147
147
  Perform one connection-level (COM_XXXX) command.
148
148
 
169
169
{
170
170
  bool error= 0;
171
171
  Query_id &query_id= Query_id::get_query_id();
 
172
  plugin::Registry &plugins= plugin::Registry::singleton();
172
173
 
173
 
  DRIZZLE_COMMAND_START(session->thread_id, command);
 
174
  DRIZZLE_COMMAND_START(session->thread_id,
 
175
                        command);
174
176
 
175
177
  session->command= command;
176
178
  session->lex->sql_command= SQLCOM_END; /* to avoid confusing VIEW detectors */
177
179
  session->set_time();
178
 
  session->setQueryId(query_id.value());
 
180
  session->query_id= query_id.value();
179
181
 
180
182
  switch( command ) {
181
183
  /* Ignore these statements. */
183
185
    break;
184
186
  /* Increase id and count all other statements. */
185
187
  default:
186
 
    session->status_var.questions++;
 
188
    statistic_increment(session->status_var.questions, &LOCK_status);
187
189
    query_id.next();
188
190
  }
189
191
 
190
192
  /* TODO: set session->lex->sql_command to SQLCOM_END here */
191
193
 
192
 
  plugin::Logging::preDo(session);
193
 
  if (unlikely(plugin::EventObserver::beforeStatement(*session)))
194
 
  {
195
 
    // We should do something about an error...
196
 
  }
 
194
  plugins.logging.pre_do(session);
197
195
 
198
196
  session->server_status&=
199
197
           ~(SERVER_QUERY_NO_INDEX_USED | SERVER_QUERY_NO_GOOD_INDEX_USED);
200
198
  switch (command) {
201
199
  case COM_INIT_DB:
202
200
  {
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))
 
201
    LEX_STRING tmp;
 
202
    status_var_increment(session->status_var.com_stat[SQLCOM_CHANGE_DB]);
 
203
    tmp.str= packet;
 
204
    tmp.length= packet_length;
 
205
    if (!mysql_change_db(session, &tmp, false))
214
206
    {
215
207
      session->my_ok();
216
208
    }
218
210
  }
219
211
  case COM_QUERY:
220
212
  {
221
 
    if (not session->readAndStoreQuery(packet, packet_length))
 
213
    if (! session->readAndStoreQuery(packet, packet_length))
222
214
      break;                                    // fatal error is set
223
 
    DRIZZLE_QUERY_START(session->getQueryString()->c_str(),
 
215
    DRIZZLE_QUERY_START(session->query,
224
216
                        session->thread_id,
225
 
                        const_cast<const char *>(session->schema()->c_str()));
 
217
                        const_cast<const char *>(session->db ? session->db : ""));
 
218
    const char* end_of_stmt= NULL;
226
219
 
227
 
    mysql_parse(session, session->getQueryString()->c_str(), session->getQueryString()->length());
 
220
    mysql_parse(session, session->query, session->query_length, &end_of_stmt);
228
221
 
229
222
    break;
230
223
  }
235
228
    break;
236
229
  case COM_SHUTDOWN:
237
230
  {
238
 
    session->status_var.com_other++;
 
231
    status_var_increment(session->status_var.com_other);
239
232
    session->my_eof();
240
233
    session->close_thread_tables();                     // Free before kill
241
234
    kill_drizzle();
243
236
    break;
244
237
  }
245
238
  case COM_PING:
246
 
    session->status_var.com_other++;
 
239
    status_var_increment(session->status_var.com_other);
247
240
    session->my_ok();                           // Tell client we are alive
248
241
    break;
249
242
  case COM_SLEEP:
256
249
 
257
250
  /* If commit fails, we should be able to reset the OK status. */
258
251
  session->main_da.can_overwrite_status= true;
259
 
  TransactionServices &transaction_services= TransactionServices::singleton();
260
 
  transaction_services.autocommitOrRollback(session, session->is_error());
 
252
  ha_autocommit_or_rollback(session, session->is_error());
261
253
  session->main_da.can_overwrite_status= false;
262
254
 
263
255
  session->transaction.stmt.reset();
269
261
    if (! session->main_da.is_set())
270
262
      session->send_kill_message();
271
263
  }
272
 
  if (session->getKilled() == Session::KILL_QUERY || session->getKilled() == Session::KILL_BAD_DATA)
 
264
  if (session->killed == Session::KILL_QUERY || session->killed == Session::KILL_BAD_DATA)
273
265
  {
274
 
    session->setKilled(Session::NOT_KILLED);
275
 
    session->setAbort(false);
 
266
    session->killed= Session::NOT_KILLED;
 
267
    session->mysys_var->abort= 0;
276
268
  }
277
269
 
278
270
  /* Can not be true, but do not take chances in production. */
309
301
  /* Free tables */
310
302
  session->close_thread_tables();
311
303
 
312
 
  plugin::Logging::postDo(session);
313
 
  if (unlikely(plugin::EventObserver::afterStatement(*session)))
314
 
  {
315
 
    // We should do something about an error...
316
 
  }
 
304
  plugins.logging.post_do(session);
317
305
 
318
306
  /* Store temp state for processlist */
319
307
  session->set_proc_info("cleaning up");
320
308
  session->command= COM_SLEEP;
321
 
  session->resetQueryString();
 
309
  memset(session->process_list_info, 0, PROCESS_LIST_WIDTH);
 
310
  session->query= 0;
 
311
  session->query_length= 0;
322
312
 
323
313
  session->set_proc_info(NULL);
324
 
  session->mem_root->free_root(MYF(memory::KEEP_PREALLOC));
 
314
  session->packet.shrink(session->variables.net_buffer_length); // Reclaim some memory
 
315
  free_root(session->mem_root,MYF(MY_KEEP_PREALLOC));
325
316
 
326
317
  if (DRIZZLE_QUERY_DONE_ENABLED() || DRIZZLE_COMMAND_DONE_ENABLED())
327
318
  {
361
352
    1                 out of memory or SHOW commands are not allowed
362
353
                      in this version of the server.
363
354
*/
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)
 
355
 
 
356
int prepare_schema_table(Session *session, LEX *lex, Table_ident *table_ident,
 
357
                         const string& schema_table_name)
386
358
{
387
359
  Select_Lex *schema_select_lex= NULL;
388
360
 
 
361
 
 
362
  if (schema_table_name.compare("TABLES") == 0 ||
 
363
      schema_table_name.compare("TABLE_NAMES") == 0)
 
364
  {
 
365
    LEX_STRING db;
 
366
    size_t dummy;
 
367
    if (lex->select_lex.db == NULL &&
 
368
        lex->copy_db_to(&lex->select_lex.db, &dummy))
 
369
    {
 
370
      return (1);
 
371
    }
 
372
    schema_select_lex= new Select_Lex();
 
373
    db.str= schema_select_lex->db= lex->select_lex.db;
 
374
    schema_select_lex->table_list.first= NULL;
 
375
    db.length= strlen(db.str);
 
376
 
 
377
    if (check_db_name(&db))
 
378
    {
 
379
      my_error(ER_WRONG_DB_NAME, MYF(0), db.str);
 
380
      return (1);
 
381
    }
 
382
  }
 
383
  else if (schema_table_name.compare("COLUMNS") == 0 ||
 
384
           schema_table_name.compare("STATISTICS") == 0)
 
385
  {
 
386
    assert(table_ident);
 
387
    TableList **query_tables_last= lex->query_tables_last;
 
388
    schema_select_lex= new Select_Lex();
 
389
    /* 'parent_lex' is used in init_query() so it must be before it. */
 
390
    schema_select_lex->parent_lex= lex;
 
391
    schema_select_lex->init_query();
 
392
    if (! schema_select_lex->add_table_to_list(session, table_ident, 0, 0, TL_READ))
 
393
    {
 
394
      return (1);
 
395
    }
 
396
    lex->query_tables_last= query_tables_last;
 
397
  }
 
398
 
389
399
  Select_Lex *select_lex= lex->current_select;
390
400
  assert(select_lex);
391
 
  if (_schema_select(session, select_lex, schema_table_name))
 
401
  if (make_schema_select(session, select_lex, schema_table_name))
392
402
  {
393
403
    return(1);
394
404
  }
429
439
    true        Error
430
440
*/
431
441
 
432
 
static int mysql_execute_command(Session *session)
 
442
static int
 
443
mysql_execute_command(Session *session)
433
444
{
434
445
  bool res= false;
435
446
  LEX  *lex= session->lex;
437
448
  Select_Lex *select_lex= &lex->select_lex;
438
449
  /* list of all tables in query */
439
450
  TableList *all_tables;
 
451
  /* A peek into the query string */
 
452
  size_t proc_info_len= session->query_length > PROCESS_LIST_WIDTH ?
 
453
                        PROCESS_LIST_WIDTH : session->query_length;
 
454
 
 
455
  memcpy(session->process_list_info, session->query, proc_info_len);
 
456
  session->process_list_info[proc_info_len]= '\0';
440
457
 
441
458
  /*
442
459
    In many cases first table of main Select_Lex have special meaning =>
473
490
    drizzle_reset_errors(session, 0);
474
491
  }
475
492
 
476
 
  assert(session->transaction.stmt.hasModifiedNonTransData() == false);
 
493
  status_var_increment(session->status_var.com_stat[lex->sql_command]);
 
494
 
 
495
  assert(session->transaction.stmt.modified_non_trans_table == false);
477
496
 
478
497
  /* now we are ready to execute the statement */
479
498
  res= lex->statement->execute();
 
499
 
480
500
  session->set_proc_info("query end");
 
501
 
481
502
  /*
482
503
    The return value for ROW_COUNT() is "implementation dependent" if the
483
504
    statement is not DELETE, INSERT or UPDATE, but -1 is what JDBC and ODBC
491
512
 
492
513
  return (res || session->is_error());
493
514
}
 
515
 
494
516
bool execute_sqlcom_select(Session *session, TableList *all_tables)
495
517
{
496
518
  LEX   *lex= session->lex;
503
525
      param->select_limit=
504
526
        new Item_int((uint64_t) session->variables.select_limit);
505
527
  }
506
 
  if (not (res= session->openTablesLock(all_tables)))
 
528
  if (!(res= session->openTablesLock(all_tables)))
507
529
  {
508
530
    if (lex->describe)
509
531
    {
516
538
      if (!(result= new select_send()))
517
539
        return true;
518
540
      session->send_explain_fields(result);
519
 
      optimizer::ExplainPlan planner;
520
 
      res= planner.explainUnion(session, &session->lex->unit, result);
 
541
      res= mysql_explain_union(session, &session->lex->unit, result);
521
542
      if (lex->describe & DESCRIBE_EXTENDED)
522
543
      {
523
544
        char buff[1024];
538
559
    {
539
560
      if (!result && !(result= new select_send()))
540
561
        return true;
541
 
 
542
 
      /* Init the Query Cache plugin */
543
 
      plugin::QueryCache::prepareResultset(session); 
544
562
      res= handle_select(session, lex, result, 0);
545
 
      /* Send the Resultset to the cache */
546
 
      plugin::QueryCache::setResultset(session); 
547
 
 
548
563
      if (result != lex->result)
549
564
        delete result;
550
565
    }
698
713
  */
699
714
  if ((var= get_system_var(session, OPT_SESSION, tmp, null_lex_string)))
700
715
  {
701
 
    end+= snprintf(buff, sizeof(buff), "@@session.%s", var_name);
 
716
    end+= sprintf(buff, "@@session.%s", var_name);
702
717
    var->set_name(buff, end-buff, system_charset_info);
703
718
    session->add_item_to_list(var);
704
719
  }
712
727
  @param       session     Current thread
713
728
  @param       inBuf   Begining of the query text
714
729
  @param       length  Length of the query text
 
730
  @param[out]  found_semicolon For multi queries, position of the character of
 
731
                               the next query in the query text.
715
732
*/
716
733
 
717
 
void mysql_parse(Session *session, const char *inBuf, uint32_t length)
 
734
void mysql_parse(Session *session, const char *inBuf, uint32_t length,
 
735
                 const char ** found_semicolon)
718
736
{
719
 
  boost::posix_time::ptime start_time=boost::posix_time::microsec_clock::local_time();
720
 
  session->lex->start(session);
721
 
 
 
737
  /*
 
738
    Warning.
 
739
    The purpose of query_cache_send_result_to_client() is to lookup the
 
740
    query in the query cache first, to avoid parsing and executing it.
 
741
    So, the natural implementation would be to:
 
742
    - first, call query_cache_send_result_to_client,
 
743
    - second, if caching failed, initialise the lexical and syntactic parser.
 
744
    The problem is that the query cache depends on a clean initialization
 
745
    of (among others) lex->safe_to_cache_query and session->server_status,
 
746
    which are reset respectively in
 
747
    - lex_start()
 
748
    - mysql_reset_session_for_next_command()
 
749
    So, initializing the lexical analyser *before* using the query cache
 
750
    is required for the cache to work properly.
 
751
    FIXME: cleanup the dependencies in the code to simplify this.
 
752
  */
 
753
  lex_start(session);
722
754
  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
 
  {
 
755
 
 
756
  {
 
757
    LEX *lex= session->lex;
 
758
 
 
759
    Lex_input_stream lip(session, inBuf, length);
 
760
 
 
761
    bool err= parse_sql(session, &lip);
 
762
    *found_semicolon= lip.found_semicolon;
 
763
 
 
764
    if (!err)
741
765
    {
742
 
      if (not session->is_error())
743
766
      {
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
 
        {
 
767
        if (! session->is_error())
 
768
        {
 
769
          /*
 
770
            Binlog logs a string starting from session->query and having length
 
771
            session->query_length; so we set session->query_length correctly (to not
 
772
            log several statements in one event, when we executed only first).
 
773
            We set it to not see the ';' (otherwise it would get into binlog
 
774
            and Query_log_event::print() would give ';;' output).
 
775
            This also helps display only the current query in SHOW
 
776
            PROCESSLIST.
 
777
            Note that we don't need LOCK_thread_count to modify query_length.
 
778
          */
 
779
          if (*found_semicolon &&
 
780
              (session->query_length= (ulong)(*found_semicolon - session->query)))
 
781
            session->query_length--;
 
782
          DRIZZLE_QUERY_EXEC_START(session->query,
 
783
                                   session->thread_id,
 
784
                                   const_cast<const char *>(session->db ? session->db : ""));
 
785
          /* Actually execute the query */
751
786
          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);
 
787
          DRIZZLE_QUERY_EXEC_DONE(0);
 
788
        }
760
789
      }
761
790
    }
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();
 
791
    else
 
792
    {
 
793
      assert(session->is_error());
 
794
    }
 
795
    lex->unit.cleanup();
 
796
    session->set_proc_info("freeing items");
 
797
    session->end_statement();
 
798
    session->cleanup_after_query();
 
799
  }
 
800
 
 
801
  return;
773
802
}
774
803
 
775
804
 
792
821
{
793
822
  register CreateField *new_field;
794
823
  LEX  *lex= session->lex;
795
 
  statement::AlterTable *statement= (statement::AlterTable *)lex->statement;
796
824
 
797
825
  if (check_identifier_name(field_name, ER_TOO_LONG_IDENT))
798
 
    return true;
 
826
    return(1);
799
827
 
800
828
  if (type_modifier & PRI_KEY_FLAG)
801
829
  {
804
832
    key= new Key(Key::PRIMARY, null_lex_str,
805
833
                      &default_key_create_info,
806
834
                      0, lex->col_list);
807
 
    statement->alter_info.key_list.push_back(key);
 
835
    lex->alter_info.key_list.push_back(key);
808
836
    lex->col_list.empty();
809
837
  }
810
838
  if (type_modifier & (UNIQUE_FLAG | UNIQUE_KEY_FLAG))
814
842
    key= new Key(Key::UNIQUE, null_lex_str,
815
843
                 &default_key_create_info, 0,
816
844
                 lex->col_list);
817
 
    statement->alter_info.key_list.push_back(key);
 
845
    lex->alter_info.key_list.push_back(key);
818
846
    lex->col_list.empty();
819
847
  }
820
848
 
832
860
         type == DRIZZLE_TYPE_TIMESTAMP))
833
861
    {
834
862
      my_error(ER_INVALID_DEFAULT, MYF(0), field_name->str);
835
 
      return true;
 
863
      return(1);
836
864
    }
837
865
    else if (default_value->type() == Item::NULL_ITEM)
838
866
    {
841
869
          NOT_NULL_FLAG)
842
870
      {
843
871
        my_error(ER_INVALID_DEFAULT, MYF(0), field_name->str);
844
 
        return true;
 
872
        return(1);
845
873
      }
846
874
    }
847
875
    else if (type_modifier & AUTO_INCREMENT_FLAG)
848
876
    {
849
877
      my_error(ER_INVALID_DEFAULT, MYF(0), field_name->str);
850
 
      return true;
 
878
      return(1);
851
879
    }
852
880
  }
853
881
 
854
882
  if (on_update_value && type != DRIZZLE_TYPE_TIMESTAMP)
855
883
  {
856
884
    my_error(ER_INVALID_ON_UPDATE, MYF(0), field_name->str);
857
 
    return true;
 
885
    return(1);
858
886
  }
859
887
 
860
888
  if (!(new_field= new CreateField()) ||
861
889
      new_field->init(session, field_name->str, type, length, decimals, type_modifier,
862
890
                      default_value, on_update_value, comment, change,
863
891
                      interval_list, cs, 0, column_format))
864
 
    return true;
 
892
    return(1);
865
893
 
866
 
  statement->alter_info.create_list.push_back(new_field);
 
894
  lex->alter_info.create_list.push_back(new_field);
867
895
  lex->last_field=new_field;
868
 
 
869
 
  return false;
 
896
  return(0);
870
897
}
871
898
 
872
899
 
897
924
*/
898
925
 
899
926
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)
 
927
                                             Table_ident *table,
 
928
                                             LEX_STRING *alias,
 
929
                                             uint32_t table_options,
 
930
                                             thr_lock_type lock_type,
 
931
                                             List<Index_hint> *index_hints_arg,
 
932
                                             LEX_STRING *option)
906
933
{
907
 
  TableList *ptr;
 
934
  register TableList *ptr;
908
935
  TableList *previous_table_ref; /* The table preceding the current one. */
909
936
  char *alias_str;
910
937
  LEX *lex= session->lex;
912
939
  if (!table)
913
940
    return NULL;                                // End of memory
914
941
  alias_str= alias ? alias->str : table->table.str;
915
 
  if (! table_options.test(TL_OPTION_ALIAS) &&
 
942
  if (!test(table_options & TL_OPTION_ALIAS) &&
916
943
      check_table_name(table->table.str, table->table.length))
917
944
  {
918
945
    my_error(ER_WRONG_TABLE_NAME, MYF(0), table->table.str);
919
946
    return NULL;
920
947
  }
921
948
 
922
 
  if (table->is_derived_table() == false && table->db.str)
 
949
  if (table->is_derived_table() == false && table->db.str &&
 
950
      check_db_name(&table->db))
923
951
  {
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
 
    }
 
952
    my_error(ER_WRONG_DB_NAME, MYF(0), table->db.str);
 
953
    return NULL;
933
954
  }
934
955
 
935
956
  if (!alias)                                   /* Alias is case sensitive */
945
966
  }
946
967
  if (!(ptr = (TableList *) session->calloc(sizeof(TableList))))
947
968
    return NULL;
948
 
 
949
969
  if (table->db.str)
950
970
  {
951
 
    ptr->setIsFqtn(true);
952
 
    ptr->setSchemaName(table->db.str);
 
971
    ptr->is_fqtn= true;
 
972
    ptr->db= table->db.str;
953
973
    ptr->db_length= table->db.length;
954
974
  }
955
 
  else if (lex->copy_db_to(ptr->getSchemaNamePtr(), &ptr->db_length))
 
975
  else if (lex->copy_db_to(&ptr->db, &ptr->db_length))
956
976
    return NULL;
957
977
  else
958
 
    ptr->setIsFqtn(false);
 
978
    ptr->is_fqtn= false;
959
979
 
960
980
  ptr->alias= alias_str;
961
 
  ptr->setIsAlias(alias ? true : false);
962
 
  ptr->setTableName(table->table.str);
 
981
  ptr->is_alias= alias ? true : false;
 
982
  if (table->table.length)
 
983
    table->table.length= my_casedn_str(files_charset_info, table->table.str);
 
984
  ptr->table_name=table->table.str;
963
985
  ptr->table_name_length=table->table.length;
964
986
  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);
 
987
  ptr->updating=    test(table_options & TL_OPTION_UPDATING);
 
988
  ptr->force_index= test(table_options & TL_OPTION_FORCE_INDEX);
 
989
  ptr->ignore_leaves= test(table_options & TL_OPTION_IGNORE_LEAVES);
967
990
  ptr->derived=     table->sel;
 
991
  if (!ptr->derived && !my_strcasecmp(system_charset_info, ptr->db,
 
992
                                      INFORMATION_SCHEMA_NAME.c_str()))
 
993
  {
 
994
    plugin::InfoSchemaTable *schema_table= find_schema_table(ptr->table_name);
 
995
    if (!schema_table ||
 
996
        (schema_table->isHidden() &&
 
997
         ((sql_command_flags[lex->sql_command].test(CF_BIT_STATUS_COMMAND)) == 0 ||
 
998
          /*
 
999
            this check is used for show columns|keys from I_S hidden table
 
1000
          */
 
1001
          lex->sql_command == SQLCOM_SHOW_FIELDS ||
 
1002
          lex->sql_command == SQLCOM_SHOW_KEYS)))
 
1003
    {
 
1004
      my_error(ER_UNKNOWN_TABLE, MYF(0),
 
1005
               ptr->table_name, INFORMATION_SCHEMA_NAME.c_str());
 
1006
      return NULL;
 
1007
    }
 
1008
    ptr->schema_table_name= ptr->table_name;
 
1009
    ptr->schema_table= schema_table;
 
1010
  }
968
1011
  ptr->select_lex=  lex->current_select;
969
1012
  ptr->index_hints= index_hints_arg;
970
1013
  ptr->option= option ? option->str : 0;
977
1020
         tables=tables->next_local)
978
1021
    {
979
1022
      if (!my_strcasecmp(table_alias_charset, alias_str, tables->alias) &&
980
 
          !strcasecmp(ptr->getSchemaName(), tables->getSchemaName()))
 
1023
          !strcmp(ptr->db, tables->db))
981
1024
      {
982
1025
        my_error(ER_NONUNIQ_TABLE, MYF(0), alias_str);
983
1026
        return NULL;
1046
1089
  if (!(ptr= (TableList*) session->calloc(ALIGN_SIZE(sizeof(TableList))+
1047
1090
                                       sizeof(nested_join_st))))
1048
1091
    return true;
1049
 
  ptr->setNestedJoin(((nested_join_st*) ((unsigned char*) ptr + ALIGN_SIZE(sizeof(TableList)))));
1050
 
  nested_join= ptr->getNestedJoin();
 
1092
  nested_join= ptr->nested_join=
 
1093
    ((nested_join_st*) ((unsigned char*) ptr + ALIGN_SIZE(sizeof(TableList))));
 
1094
 
1051
1095
  join_list->push_front(ptr);
1052
 
  ptr->setEmbedding(embedding);
1053
 
  ptr->setJoinList(join_list);
 
1096
  ptr->embedding= embedding;
 
1097
  ptr->join_list= join_list;
1054
1098
  ptr->alias= (char*) "(nested_join)";
1055
1099
  embedding= ptr;
1056
1100
  join_list= &nested_join->join_list;
1080
1124
 
1081
1125
  assert(embedding);
1082
1126
  ptr= embedding;
1083
 
  join_list= ptr->getJoinList();
1084
 
  embedding= ptr->getEmbedding();
1085
 
  nested_join= ptr->getNestedJoin();
 
1127
  join_list= ptr->join_list;
 
1128
  embedding= ptr->embedding;
 
1129
  nested_join= ptr->nested_join;
1086
1130
  if (nested_join->join_list.elements == 1)
1087
1131
  {
1088
1132
    TableList *embedded= nested_join->join_list.head();
1089
1133
    join_list->pop();
1090
 
    embedded->setJoinList(join_list);
1091
 
    embedded->setEmbedding(embedding);
 
1134
    embedded->join_list= join_list;
 
1135
    embedded->embedding= embedding;
1092
1136
    join_list->push_front(embedded);
1093
1137
    ptr= embedded;
1094
1138
  }
1121
1165
  List<TableList> *embedded_list;
1122
1166
 
1123
1167
  if (!(ptr= (TableList*) session->calloc(ALIGN_SIZE(sizeof(TableList))+
1124
 
                                          sizeof(nested_join_st))))
 
1168
                                       sizeof(nested_join_st))))
1125
1169
    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);
 
1170
  nested_join= ptr->nested_join=
 
1171
    ((nested_join_st*) ((unsigned char*) ptr + ALIGN_SIZE(sizeof(TableList))));
 
1172
 
 
1173
  ptr->embedding= embedding;
 
1174
  ptr->join_list= join_list;
1130
1175
  ptr->alias= (char*) "(nest_last_join)";
1131
1176
  embedded_list= &nested_join->join_list;
1132
1177
  embedded_list->empty();
1134
1179
  for (uint32_t i=0; i < 2; i++)
1135
1180
  {
1136
1181
    TableList *table= join_list->pop();
1137
 
    table->setJoinList(embedded_list);
1138
 
    table->setEmbedding(ptr);
 
1182
    table->join_list= embedded_list;
 
1183
    table->embedding= ptr;
1139
1184
    embedded_list->push_back(table);
1140
1185
    if (table->natural_join)
1141
1186
    {
1171
1216
void Select_Lex::add_joined_table(TableList *table)
1172
1217
{
1173
1218
  join_list->push_front(table);
1174
 
  table->setJoinList(join_list);
1175
 
  table->setEmbedding(embedding);
 
1219
  table->join_list= join_list;
 
1220
  table->embedding= embedding;
1176
1221
}
1177
1222
 
1178
1223
 
1232
1277
 
1233
1278
void Select_Lex::set_lock_for_tables(thr_lock_type lock_type)
1234
1279
{
 
1280
  bool for_update= lock_type >= TL_READ_NO_INSERT;
 
1281
 
1235
1282
  for (TableList *tables= (TableList*) table_list.first;
1236
1283
       tables;
1237
1284
       tables= tables->next_local)
1238
1285
  {
1239
1286
    tables->lock_type= lock_type;
 
1287
    tables->updating=  for_update;
1240
1288
  }
 
1289
  return;
1241
1290
}
1242
1291
 
1243
1292
 
1248
1297
    This object is created for any union construct containing a union
1249
1298
    operation and also for any single select union construct of the form
1250
1299
    @verbatim
1251
 
    (SELECT ... ORDER BY order_list [LIMIT n]) ORDER BY ...
 
1300
    (SELECT ... order_st BY order_list [LIMIT n]) order_st BY ...
1252
1301
    @endvarbatim
1253
1302
    or of the form
1254
1303
    @varbatim
1255
 
    (SELECT ... ORDER BY LIMIT n) ORDER BY ...
 
1304
    (SELECT ... order_st BY LIMIT n) order_st BY ...
1256
1305
    @endvarbatim
1257
1306
 
1258
1307
  @param session_arg               thread handle
1283
1332
  fake_select_lex->select_limit= 0;
1284
1333
 
1285
1334
  fake_select_lex->context.outer_context=first_sl->context.outer_context;
1286
 
  /* allow item list resolving in fake select for ORDER BY */
 
1335
  /* allow item list resolving in fake select for order_st BY */
1287
1336
  fake_select_lex->context.resolve_in_select_list= true;
1288
1337
  fake_select_lex->context.select_lex= fake_select_lex;
1289
1338
 
1291
1340
  {
1292
1341
    /*
1293
1342
      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]
 
1343
      (SELECT ... order_st BY list [LIMIT n]) order_st BY order_list [LIMIT m],
 
1344
      (SELECT ... LIMIT n) order_st BY order_list [LIMIT m]
1296
1345
      just before the parser starts processing order_list
1297
1346
    */
1298
1347
    global_parameters= fake_select_lex;
1415
1464
 
1416
1465
 
1417
1466
/**
 
1467
  kill on thread.
 
1468
 
 
1469
  @param session                        Thread class
 
1470
  @param id                     Thread id
 
1471
  @param only_kill_query        Should it kill the query or the connection
 
1472
 
 
1473
  @note
 
1474
    This is written such that we have a short lock on LOCK_thread_count
 
1475
*/
 
1476
 
 
1477
static unsigned int
 
1478
kill_one_thread(Session *, ulong id, bool only_kill_query)
 
1479
{
 
1480
  Session *tmp= NULL;
 
1481
  uint32_t error=ER_NO_SUCH_THREAD;
 
1482
  pthread_mutex_lock(&LOCK_thread_count); // For unlink from list
 
1483
  
 
1484
  for( vector<Session*>::iterator it= session_list.begin(); it != session_list.end(); ++it )
 
1485
  {
 
1486
    if ((*it)->thread_id == id)
 
1487
    {
 
1488
      tmp= *it;
 
1489
      pthread_mutex_lock(&tmp->LOCK_delete);    // Lock from delete
 
1490
      break;
 
1491
    }
 
1492
  }
 
1493
  pthread_mutex_unlock(&LOCK_thread_count);
 
1494
  if (tmp)
 
1495
  {
 
1496
    tmp->awake(only_kill_query ? Session::KILL_QUERY : Session::KILL_CONNECTION);
 
1497
    error=0;
 
1498
    pthread_mutex_unlock(&tmp->LOCK_delete);
 
1499
  }
 
1500
  return(error);
 
1501
}
 
1502
 
 
1503
 
 
1504
/*
 
1505
  kills a thread and sends response
 
1506
 
 
1507
  SYNOPSIS
 
1508
    sql_kill()
 
1509
    session                     Thread class
 
1510
    id                  Thread id
 
1511
    only_kill_query     Should it kill the query or the connection
 
1512
*/
 
1513
 
 
1514
void sql_kill(Session *session, ulong id, bool only_kill_query)
 
1515
{
 
1516
  uint32_t error;
 
1517
  if (!(error= kill_one_thread(session, id, only_kill_query)))
 
1518
    session->my_ok();
 
1519
  else
 
1520
    my_error(error, MYF(0), id);
 
1521
}
 
1522
 
 
1523
 
 
1524
/**
1418
1525
  Check if the select is a simple select (not an union).
1419
1526
 
1420
1527
  @retval
1542
1649
 
1543
1650
 
1544
1651
/**
 
1652
  CREATE TABLE query pre-check.
 
1653
 
 
1654
  @param session                        Thread handler
 
1655
  @param tables         Global table list
 
1656
  @param create_table           Table which will be created
 
1657
 
 
1658
  @retval
 
1659
    false   OK
 
1660
  @retval
 
1661
    true   Error
 
1662
*/
 
1663
 
 
1664
bool create_table_precheck(Session *, TableList *,
 
1665
                           TableList *create_table)
 
1666
{
 
1667
  bool error= true;                                 // Error message is given
 
1668
 
 
1669
  if (create_table && (strcmp(create_table->db, "information_schema") == 0))
 
1670
  {
 
1671
    my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), "", "", INFORMATION_SCHEMA_NAME.c_str());
 
1672
    return(true);
 
1673
  }
 
1674
 
 
1675
  error= false;
 
1676
 
 
1677
  return(error);
 
1678
}
 
1679
 
 
1680
 
 
1681
/**
1545
1682
  negate given expression.
1546
1683
 
1547
1684
  @param session  thread handler
1650
1787
}
1651
1788
 
1652
1789
 
 
1790
/*
 
1791
  Check if path does not contain mysql data home directory
 
1792
  SYNOPSIS
 
1793
    test_if_data_home_dir()
 
1794
    dir                     directory
 
1795
    conv_home_dir           converted data home directory
 
1796
    home_dir_len            converted data home directory length
 
1797
 
 
1798
  RETURN VALUES
 
1799
    0   ok
 
1800
    1   error
 
1801
*/
 
1802
 
 
1803
bool test_if_data_home_dir(const char *dir)
 
1804
{
 
1805
  char path[FN_REFLEN], conv_path[FN_REFLEN];
 
1806
  uint32_t dir_len, home_dir_len= strlen(drizzle_unpacked_real_data_home);
 
1807
 
 
1808
  if (!dir)
 
1809
    return(0);
 
1810
 
 
1811
  (void) fn_format(path, dir, "", "",
 
1812
                   (MY_RETURN_REAL_PATH|MY_RESOLVE_SYMLINKS));
 
1813
  dir_len= unpack_dirname(conv_path, dir);
 
1814
 
 
1815
  if (home_dir_len < dir_len)
 
1816
  {
 
1817
    if (!my_strnncoll(character_set_filesystem,
 
1818
                      (const unsigned char*) conv_path, home_dir_len,
 
1819
                      (const unsigned char*) drizzle_unpacked_real_data_home,
 
1820
                      home_dir_len))
 
1821
      return(1);
 
1822
  }
 
1823
  return(0);
 
1824
}
 
1825
 
 
1826
 
 
1827
extern int DRIZZLEparse(void *session); // from sql_yacc.cc
 
1828
 
 
1829
 
1653
1830
/**
1654
1831
  This is a wrapper of DRIZZLEparse(). All the code should call parse_sql()
1655
1832
  instead of DRIZZLEparse().
1662
1839
    @retval true on parsing error.
1663
1840
*/
1664
1841
 
1665
 
static bool parse_sql(Session *session, Lex_input_stream *lip)
 
1842
bool parse_sql(Session *session, Lex_input_stream *lip)
1666
1843
{
1667
1844
  assert(session->m_lip == NULL);
1668
1845
 
1669
 
  DRIZZLE_QUERY_PARSE_START(session->getQueryString()->c_str());
 
1846
  DRIZZLE_QUERY_PARSE_START(session->query);
1670
1847
 
1671
1848
  /* Set Lex_input_stream. */
1672
1849
 
1694
1871
/**
1695
1872
  @} (end of group Runtime_Environment)
1696
1873
*/
1697
 
 
1698
 
} /* namespace drizzled */