~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_parse.cc

  • Committer: Monty Taylor
  • Date: 2010-01-02 05:11:55 UTC
  • mto: (1259.3.1 build)
  • mto: This revision was merged to the branch mainline in revision 1262.
  • Revision ID: mordred@inaugust.com-20100102051155-akdm8w5rr6xwzayu
pandora-build - proper detection of memcached.

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
#define DRIZZLE_LEX 1
16
17
#include "config.h"
17
 
 
18
 
#define DRIZZLE_LEX 1
19
 
 
20
18
#include <drizzled/my_hash.h>
21
19
#include <drizzled/error.h>
22
20
#include <drizzled/nested_join.h>
23
21
#include <drizzled/query_id.h>
24
 
#include "drizzled/transaction_services.h"
25
22
#include <drizzled/sql_parse.h>
26
23
#include <drizzled/data_home.h>
27
24
#include <drizzled/sql_base.h>
28
25
#include <drizzled/show.h>
29
26
#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>
39
37
#include <drizzled/statement.h>
40
38
#include <drizzled/statement/alter_table.h>
41
39
#include "drizzled/probes.h"
42
 
#include "drizzled/session/cache.h"
 
40
#include "drizzled/session_list.h"
43
41
#include "drizzled/global_charset_info.h"
44
42
 
 
43
 
45
44
#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"
 
45
#include "drizzled/plugin/info_schema_table.h"
49
46
#include "drizzled/optimizer/explain_plan.h"
50
47
#include "drizzled/pthread_globals.h"
51
 
#include "drizzled/plugin/event_observer.h"
52
48
 
53
49
#include <limits.h>
54
50
 
55
51
#include <bitset>
56
52
#include <algorithm>
57
 
#include <boost/date_time.hpp>
 
53
 
58
54
#include "drizzled/internal/my_sys.h"
59
55
 
 
56
using namespace drizzled;
60
57
using namespace std;
61
58
 
62
 
extern int DRIZZLEparse(void *session); // from sql_yacc.cc
63
 
 
64
 
namespace drizzled
65
 
{
66
 
 
67
59
/* Prototypes */
68
60
bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
69
61
static bool parse_sql(Session *session, Lex_input_stream *lip);
70
 
void mysql_parse(Session *session, const char *inBuf, uint32_t length);
 
62
static void mysql_parse(Session *session, const char *inBuf, uint32_t length,
 
63
                 const char ** found_semicolon);
71
64
 
72
65
/**
73
66
  @defgroup Runtime_Environment Runtime Environment
131
124
  sql_command_flags[SQLCOM_REPLACE]=        CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
132
125
  sql_command_flags[SQLCOM_REPLACE_SELECT]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
133
126
 
 
127
  sql_command_flags[SQLCOM_SHOW_STATUS]=      CF_STATUS_COMMAND;
 
128
  sql_command_flags[SQLCOM_SHOW_DATABASES]=   CF_STATUS_COMMAND;
 
129
  sql_command_flags[SQLCOM_SHOW_OPEN_TABLES]= CF_STATUS_COMMAND;
 
130
  sql_command_flags[SQLCOM_SHOW_FIELDS]=      CF_STATUS_COMMAND;
 
131
  sql_command_flags[SQLCOM_SHOW_KEYS]=        CF_STATUS_COMMAND;
 
132
  sql_command_flags[SQLCOM_SHOW_VARIABLES]=   CF_STATUS_COMMAND;
134
133
  sql_command_flags[SQLCOM_SHOW_WARNS]= CF_STATUS_COMMAND;
135
134
  sql_command_flags[SQLCOM_SHOW_ERRORS]= CF_STATUS_COMMAND;
 
135
  sql_command_flags[SQLCOM_SHOW_ENGINE_STATUS]= CF_STATUS_COMMAND;
 
136
  sql_command_flags[SQLCOM_SHOW_PROCESSLIST]= CF_STATUS_COMMAND;
136
137
  sql_command_flags[SQLCOM_SHOW_CREATE_DB]=  CF_STATUS_COMMAND;
137
138
  sql_command_flags[SQLCOM_SHOW_CREATE]=  CF_STATUS_COMMAND;
138
139
 
 
140
   sql_command_flags[SQLCOM_SHOW_TABLES]=       (CF_STATUS_COMMAND |
 
141
                                               CF_SHOW_TABLE_COMMAND);
 
142
  sql_command_flags[SQLCOM_SHOW_TABLE_STATUS]= (CF_STATUS_COMMAND |
 
143
                                                CF_SHOW_TABLE_COMMAND);
139
144
  /*
140
145
    The following admin table operations are allowed
141
146
    on log tables.
170
175
  bool error= 0;
171
176
  Query_id &query_id= Query_id::get_query_id();
172
177
 
173
 
  DRIZZLE_COMMAND_START(session->thread_id, command);
 
178
  DRIZZLE_COMMAND_START(session->thread_id,
 
179
                        command);
174
180
 
175
181
  session->command= command;
176
182
  session->lex->sql_command= SQLCOM_END; /* to avoid confusing VIEW detectors */
177
183
  session->set_time();
178
 
  session->setQueryId(query_id.value());
 
184
  session->query_id= query_id.value();
179
185
 
180
186
  switch( command ) {
181
187
  /* Ignore these statements. */
183
189
    break;
184
190
  /* Increase id and count all other statements. */
185
191
  default:
186
 
    session->status_var.questions++;
 
192
    statistic_increment(session->status_var.questions, &LOCK_status);
187
193
    query_id.next();
188
194
  }
189
195
 
190
196
  /* TODO: set session->lex->sql_command to SQLCOM_END here */
191
197
 
192
198
  plugin::Logging::preDo(session);
193
 
  if (unlikely(plugin::EventObserver::beforeStatement(*session)))
194
 
  {
195
 
    // We should do something about an error...
196
 
  }
197
199
 
198
200
  session->server_status&=
199
201
           ~(SERVER_QUERY_NO_INDEX_USED | SERVER_QUERY_NO_GOOD_INDEX_USED);
200
202
  switch (command) {
201
203
  case COM_INIT_DB:
202
204
  {
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))
 
205
    string database_name(packet);
 
206
    NonNormalisedDatabaseName non_normalised_database_name(database_name);
 
207
    NormalisedDatabaseName normalised_database_name(non_normalised_database_name);
 
208
 
 
209
    status_var_increment(session->status_var.com_stat[SQLCOM_CHANGE_DB]);
 
210
 
 
211
    if (! mysql_change_db(session, normalised_database_name, false))
214
212
    {
215
213
      session->my_ok();
216
214
    }
218
216
  }
219
217
  case COM_QUERY:
220
218
  {
221
 
    if (not session->readAndStoreQuery(packet, packet_length))
 
219
    if (! session->readAndStoreQuery(packet, packet_length))
222
220
      break;                                    // fatal error is set
223
 
    DRIZZLE_QUERY_START(session->getQueryString()->c_str(),
 
221
    DRIZZLE_QUERY_START(session->query,
224
222
                        session->thread_id,
225
 
                        const_cast<const char *>(session->schema()->c_str()));
 
223
                        const_cast<const char *>(session->db.empty() ? "" : session->db.c_str()));
 
224
    const char* end_of_stmt= NULL;
226
225
 
227
 
    mysql_parse(session, session->getQueryString()->c_str(), session->getQueryString()->length());
 
226
    mysql_parse(session, session->query, session->query_length, &end_of_stmt);
228
227
 
229
228
    break;
230
229
  }
235
234
    break;
236
235
  case COM_SHUTDOWN:
237
236
  {
238
 
    session->status_var.com_other++;
 
237
    status_var_increment(session->status_var.com_other);
239
238
    session->my_eof();
240
239
    session->close_thread_tables();                     // Free before kill
241
240
    kill_drizzle();
243
242
    break;
244
243
  }
245
244
  case COM_PING:
246
 
    session->status_var.com_other++;
 
245
    status_var_increment(session->status_var.com_other);
247
246
    session->my_ok();                           // Tell client we are alive
248
247
    break;
249
248
  case COM_SLEEP:
256
255
 
257
256
  /* If commit fails, we should be able to reset the OK status. */
258
257
  session->main_da.can_overwrite_status= true;
259
 
  TransactionServices &transaction_services= TransactionServices::singleton();
260
 
  transaction_services.autocommitOrRollback(session, session->is_error());
 
258
  ha_autocommit_or_rollback(session, session->is_error());
261
259
  session->main_da.can_overwrite_status= false;
262
260
 
263
261
  session->transaction.stmt.reset();
269
267
    if (! session->main_da.is_set())
270
268
      session->send_kill_message();
271
269
  }
272
 
  if (session->getKilled() == Session::KILL_QUERY || session->getKilled() == Session::KILL_BAD_DATA)
 
270
  if (session->killed == Session::KILL_QUERY || session->killed == Session::KILL_BAD_DATA)
273
271
  {
274
 
    session->setKilled(Session::NOT_KILLED);
275
 
    session->setAbort(false);
 
272
    session->killed= Session::NOT_KILLED;
 
273
    session->mysys_var->abort= 0;
276
274
  }
277
275
 
278
276
  /* Can not be true, but do not take chances in production. */
310
308
  session->close_thread_tables();
311
309
 
312
310
  plugin::Logging::postDo(session);
313
 
  if (unlikely(plugin::EventObserver::afterStatement(*session)))
314
 
  {
315
 
    // We should do something about an error...
316
 
  }
317
311
 
318
312
  /* Store temp state for processlist */
319
313
  session->set_proc_info("cleaning up");
320
314
  session->command= COM_SLEEP;
321
 
  session->resetQueryString();
 
315
  memset(session->process_list_info, 0, PROCESS_LIST_WIDTH);
 
316
  session->query= 0;
 
317
  session->query_length= 0;
322
318
 
323
319
  session->set_proc_info(NULL);
324
 
  session->mem_root->free_root(MYF(memory::KEEP_PREALLOC));
 
320
  free_root(session->mem_root,MYF(memory::KEEP_PREALLOC));
325
321
 
326
322
  if (DRIZZLE_QUERY_DONE_ENABLED() || DRIZZLE_COMMAND_DONE_ENABLED())
327
323
  {
361
357
    1                 out of memory or SHOW commands are not allowed
362
358
                      in this version of the server.
363
359
*/
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)
 
360
 
 
361
int prepare_schema_table(Session *session, LEX *lex, Table_ident *table_ident,
 
362
                         const string& schema_table_name)
386
363
{
387
364
  Select_Lex *schema_select_lex= NULL;
388
365
 
 
366
 
 
367
  if (schema_table_name.compare("TABLES") == 0 ||
 
368
      schema_table_name.compare("TABLE_NAMES") == 0)
 
369
  {
 
370
    size_t dummy;
 
371
    if (lex->select_lex.db == NULL &&
 
372
        lex->copy_db_to(&lex->select_lex.db, &dummy))
 
373
    {
 
374
      return (1);
 
375
    }
 
376
    schema_select_lex= new Select_Lex();
 
377
    schema_select_lex->db= lex->select_lex.db;
 
378
 
 
379
    string database_name(schema_select_lex->db);
 
380
    NonNormalisedDatabaseName non_normalised_database_name(database_name);
 
381
    NormalisedDatabaseName normalised_database_name(non_normalised_database_name);
 
382
 
 
383
    schema_select_lex->table_list.first= NULL;
 
384
 
 
385
    if (! normalised_database_name.isValid())
 
386
    {
 
387
      my_error(ER_WRONG_DB_NAME, MYF(0),
 
388
               normalised_database_name.to_string().c_str());
 
389
      return (1);
 
390
    }
 
391
  }
 
392
  else if (schema_table_name.compare("COLUMNS") == 0 ||
 
393
           schema_table_name.compare("STATISTICS") == 0)
 
394
  {
 
395
    assert(table_ident);
 
396
    TableList **query_tables_last= lex->query_tables_last;
 
397
    schema_select_lex= new Select_Lex();
 
398
    /* 'parent_lex' is used in init_query() so it must be before it. */
 
399
    schema_select_lex->parent_lex= lex;
 
400
    schema_select_lex->init_query();
 
401
    if (! schema_select_lex->add_table_to_list(session, table_ident, 0, 0, TL_READ))
 
402
    {
 
403
      return (1);
 
404
    }
 
405
    lex->query_tables_last= query_tables_last;
 
406
  }
 
407
 
389
408
  Select_Lex *select_lex= lex->current_select;
390
409
  assert(select_lex);
391
 
  if (_schema_select(session, select_lex, schema_table_name))
 
410
  if (make_schema_select(session, select_lex, schema_table_name))
392
411
  {
393
412
    return(1);
394
413
  }
429
448
    true        Error
430
449
*/
431
450
 
432
 
static int mysql_execute_command(Session *session)
 
451
static int
 
452
mysql_execute_command(Session *session)
433
453
{
434
454
  bool res= false;
435
455
  LEX  *lex= session->lex;
437
457
  Select_Lex *select_lex= &lex->select_lex;
438
458
  /* list of all tables in query */
439
459
  TableList *all_tables;
 
460
  /* A peek into the query string */
 
461
  size_t proc_info_len= session->query_length > PROCESS_LIST_WIDTH ?
 
462
                        PROCESS_LIST_WIDTH : session->query_length;
 
463
 
 
464
  memcpy(session->process_list_info, session->query, proc_info_len);
 
465
  session->process_list_info[proc_info_len]= '\0';
440
466
 
441
467
  /*
442
468
    In many cases first table of main Select_Lex have special meaning =>
473
499
    drizzle_reset_errors(session, 0);
474
500
  }
475
501
 
476
 
  assert(session->transaction.stmt.hasModifiedNonTransData() == false);
 
502
  status_var_increment(session->status_var.com_stat[lex->sql_command]);
 
503
 
 
504
  assert(session->transaction.stmt.modified_non_trans_table == false);
477
505
 
478
506
  /* now we are ready to execute the statement */
479
507
  res= lex->statement->execute();
 
508
 
480
509
  session->set_proc_info("query end");
 
510
 
481
511
  /*
482
512
    The return value for ROW_COUNT() is "implementation dependent" if the
483
513
    statement is not DELETE, INSERT or UPDATE, but -1 is what JDBC and ODBC
491
521
 
492
522
  return (res || session->is_error());
493
523
}
 
524
 
494
525
bool execute_sqlcom_select(Session *session, TableList *all_tables)
495
526
{
496
527
  LEX   *lex= session->lex;
503
534
      param->select_limit=
504
535
        new Item_int((uint64_t) session->variables.select_limit);
505
536
  }
506
 
  if (not (res= session->openTablesLock(all_tables)))
 
537
  if (!(res= session->openTablesLock(all_tables)))
507
538
  {
508
539
    if (lex->describe)
509
540
    {
538
569
    {
539
570
      if (!result && !(result= new select_send()))
540
571
        return true;
541
 
 
542
 
      /* Init the Query Cache plugin */
543
 
      plugin::QueryCache::prepareResultset(session); 
544
572
      res= handle_select(session, lex, result, 0);
545
 
      /* Send the Resultset to the cache */
546
 
      plugin::QueryCache::setResultset(session); 
547
 
 
548
573
      if (result != lex->result)
549
574
        delete result;
550
575
    }
698
723
  */
699
724
  if ((var= get_system_var(session, OPT_SESSION, tmp, null_lex_string)))
700
725
  {
701
 
    end+= snprintf(buff, sizeof(buff), "@@session.%s", var_name);
 
726
    end+= sprintf(buff, "@@session.%s", var_name);
702
727
    var->set_name(buff, end-buff, system_charset_info);
703
728
    session->add_item_to_list(var);
704
729
  }
712
737
  @param       session     Current thread
713
738
  @param       inBuf   Begining of the query text
714
739
  @param       length  Length of the query text
 
740
  @param[out]  found_semicolon For multi queries, position of the character of
 
741
                               the next query in the query text.
715
742
*/
716
743
 
717
 
void mysql_parse(Session *session, const char *inBuf, uint32_t length)
 
744
static void mysql_parse(Session *session, const char *inBuf, uint32_t length,
 
745
                 const char ** found_semicolon)
718
746
{
719
 
  boost::posix_time::ptime start_time=boost::posix_time::microsec_clock::local_time();
720
 
  session->lex->start(session);
721
 
 
 
747
  /*
 
748
    Warning.
 
749
    The purpose of query_cache_send_result_to_client() is to lookup the
 
750
    query in the query cache first, to avoid parsing and executing it.
 
751
    So, the natural implementation would be to:
 
752
    - first, call query_cache_send_result_to_client,
 
753
    - second, if caching failed, initialise the lexical and syntactic parser.
 
754
    The problem is that the query cache depends on a clean initialization
 
755
    of (among others) lex->safe_to_cache_query and session->server_status,
 
756
    which are reset respectively in
 
757
    - lex_start()
 
758
    - mysql_reset_session_for_next_command()
 
759
    So, initializing the lexical analyser *before* using the query cache
 
760
    is required for the cache to work properly.
 
761
    FIXME: cleanup the dependencies in the code to simplify this.
 
762
  */
 
763
  lex_start(session);
722
764
  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
 
  {
 
765
 
 
766
  {
 
767
    LEX *lex= session->lex;
 
768
 
 
769
    Lex_input_stream lip(session, inBuf, length);
 
770
 
 
771
    bool err= parse_sql(session, &lip);
 
772
    *found_semicolon= lip.found_semicolon;
 
773
 
 
774
    if (!err)
741
775
    {
742
 
      if (not session->is_error())
743
776
      {
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
 
        {
 
777
        if (! session->is_error())
 
778
        {
 
779
          /*
 
780
            Binlog logs a string starting from session->query and having length
 
781
            session->query_length; so we set session->query_length correctly (to not
 
782
            log several statements in one event, when we executed only first).
 
783
            We set it to not see the ';' (otherwise it would get into binlog
 
784
            and Query_log_event::print() would give ';;' output).
 
785
            This also helps display only the current query in SHOW
 
786
            PROCESSLIST.
 
787
            Note that we don't need LOCK_thread_count to modify query_length.
 
788
          */
 
789
          if (*found_semicolon &&
 
790
              (session->query_length= (ulong)(*found_semicolon - session->query)))
 
791
            session->query_length--;
 
792
          DRIZZLE_QUERY_EXEC_START(session->query,
 
793
                                   session->thread_id,
 
794
                                   const_cast<const char *>(session->db.empty() ? "" : session->db.c_str()));
 
795
          /* Actually execute the query */
751
796
          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);
 
797
          DRIZZLE_QUERY_EXEC_DONE(0);
 
798
        }
760
799
      }
761
800
    }
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();
 
801
    else
 
802
    {
 
803
      assert(session->is_error());
 
804
    }
 
805
    lex->unit.cleanup();
 
806
    session->set_proc_info("freeing items");
 
807
    session->end_statement();
 
808
    session->cleanup_after_query();
 
809
  }
 
810
 
 
811
  return;
773
812
}
774
813
 
775
814
 
792
831
{
793
832
  register CreateField *new_field;
794
833
  LEX  *lex= session->lex;
795
 
  statement::AlterTable *statement= (statement::AlterTable *)lex->statement;
 
834
  drizzled::statement::AlterTable *statement= (drizzled::statement::AlterTable *)lex->statement;
796
835
 
797
836
  if (check_identifier_name(field_name, ER_TOO_LONG_IDENT))
798
837
    return true;
897
936
*/
898
937
 
899
938
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)
 
939
                                             Table_ident *table,
 
940
                                             LEX_STRING *alias,
 
941
                                             uint32_t table_options,
 
942
                                             thr_lock_type lock_type,
 
943
                                             List<Index_hint> *index_hints_arg,
 
944
                                             LEX_STRING *option)
906
945
{
907
 
  TableList *ptr;
 
946
  register TableList *ptr;
908
947
  TableList *previous_table_ref; /* The table preceding the current one. */
909
948
  char *alias_str;
910
949
  LEX *lex= session->lex;
912
951
  if (!table)
913
952
    return NULL;                                // End of memory
914
953
  alias_str= alias ? alias->str : table->table.str;
915
 
  if (! table_options.test(TL_OPTION_ALIAS) &&
 
954
  if (!test(table_options & TL_OPTION_ALIAS) &&
916
955
      check_table_name(table->table.str, table->table.length))
917
956
  {
918
957
    my_error(ER_WRONG_TABLE_NAME, MYF(0), table->table.str);
921
960
 
922
961
  if (table->is_derived_table() == false && table->db.str)
923
962
  {
924
 
    my_casedn_str(files_charset_info, table->db.str);
 
963
    string database_name(table->db.str);
 
964
    NonNormalisedDatabaseName non_normalised_database_name(database_name);
 
965
    NormalisedDatabaseName normalised_database_name(non_normalised_database_name);
925
966
 
926
 
    SchemaIdentifier schema_identifier(string(table->db.str));
927
 
    if (not check_db_name(session, schema_identifier))
 
967
    if (! normalised_database_name.isValid())
928
968
    {
929
 
 
930
 
      my_error(ER_WRONG_DB_NAME, MYF(0), table->db.str);
 
969
      my_error(ER_WRONG_DB_NAME, MYF(0), normalised_database_name.to_string().c_str());
931
970
      return NULL;
932
971
    }
 
972
 
 
973
    strncpy(table->db.str, normalised_database_name.to_string().c_str(),
 
974
            table->db.length);
933
975
  }
934
976
 
935
977
  if (!alias)                                   /* Alias is case sensitive */
945
987
  }
946
988
  if (!(ptr = (TableList *) session->calloc(sizeof(TableList))))
947
989
    return NULL;
948
 
 
949
990
  if (table->db.str)
950
991
  {
951
 
    ptr->setIsFqtn(true);
952
 
    ptr->setSchemaName(table->db.str);
 
992
    ptr->is_fqtn= true;
 
993
    ptr->db= table->db.str;
953
994
    ptr->db_length= table->db.length;
954
995
  }
955
 
  else if (lex->copy_db_to(ptr->getSchemaNamePtr(), &ptr->db_length))
 
996
  else if (lex->copy_db_to(&ptr->db, &ptr->db_length))
956
997
    return NULL;
957
998
  else
958
 
    ptr->setIsFqtn(false);
 
999
    ptr->is_fqtn= false;
959
1000
 
960
1001
  ptr->alias= alias_str;
961
 
  ptr->setIsAlias(alias ? true : false);
962
 
  ptr->setTableName(table->table.str);
 
1002
  ptr->is_alias= alias ? true : false;
 
1003
  if (table->table.length)
 
1004
    table->table.length= my_casedn_str(files_charset_info, table->table.str);
 
1005
  ptr->table_name=table->table.str;
963
1006
  ptr->table_name_length=table->table.length;
964
1007
  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);
 
1008
  ptr->updating=    test(table_options & TL_OPTION_UPDATING);
 
1009
  ptr->force_index= test(table_options & TL_OPTION_FORCE_INDEX);
 
1010
  ptr->ignore_leaves= test(table_options & TL_OPTION_IGNORE_LEAVES);
967
1011
  ptr->derived=     table->sel;
 
1012
  if (!ptr->derived && !my_strcasecmp(system_charset_info, ptr->db,
 
1013
                                      INFORMATION_SCHEMA_NAME.c_str()))
 
1014
  {
 
1015
    plugin::InfoSchemaTable *schema_table= plugin::InfoSchemaTable::getTable(ptr->table_name);
 
1016
    if (!schema_table ||
 
1017
        (schema_table->isHidden() &&
 
1018
         ((sql_command_flags[lex->sql_command].test(CF_BIT_STATUS_COMMAND)) == 0 ||
 
1019
          /*
 
1020
            this check is used for show columns|keys from I_S hidden table
 
1021
          */
 
1022
          lex->sql_command == SQLCOM_SHOW_FIELDS ||
 
1023
          lex->sql_command == SQLCOM_SHOW_KEYS)))
 
1024
    {
 
1025
      my_error(ER_UNKNOWN_TABLE, MYF(0),
 
1026
               ptr->table_name, INFORMATION_SCHEMA_NAME.c_str());
 
1027
      return NULL;
 
1028
    }
 
1029
  }
968
1030
  ptr->select_lex=  lex->current_select;
969
1031
  ptr->index_hints= index_hints_arg;
970
1032
  ptr->option= option ? option->str : 0;
977
1039
         tables=tables->next_local)
978
1040
    {
979
1041
      if (!my_strcasecmp(table_alias_charset, alias_str, tables->alias) &&
980
 
          !strcasecmp(ptr->getSchemaName(), tables->getSchemaName()))
 
1042
          !strcmp(ptr->db, tables->db))
981
1043
      {
982
1044
        my_error(ER_NONUNIQ_TABLE, MYF(0), alias_str);
983
1045
        return NULL;
1046
1108
  if (!(ptr= (TableList*) session->calloc(ALIGN_SIZE(sizeof(TableList))+
1047
1109
                                       sizeof(nested_join_st))))
1048
1110
    return true;
1049
 
  ptr->setNestedJoin(((nested_join_st*) ((unsigned char*) ptr + ALIGN_SIZE(sizeof(TableList)))));
1050
 
  nested_join= ptr->getNestedJoin();
 
1111
  nested_join= ptr->nested_join=
 
1112
    ((nested_join_st*) ((unsigned char*) ptr + ALIGN_SIZE(sizeof(TableList))));
 
1113
 
1051
1114
  join_list->push_front(ptr);
1052
 
  ptr->setEmbedding(embedding);
1053
 
  ptr->setJoinList(join_list);
 
1115
  ptr->embedding= embedding;
 
1116
  ptr->join_list= join_list;
1054
1117
  ptr->alias= (char*) "(nested_join)";
1055
1118
  embedding= ptr;
1056
1119
  join_list= &nested_join->join_list;
1080
1143
 
1081
1144
  assert(embedding);
1082
1145
  ptr= embedding;
1083
 
  join_list= ptr->getJoinList();
1084
 
  embedding= ptr->getEmbedding();
1085
 
  nested_join= ptr->getNestedJoin();
 
1146
  join_list= ptr->join_list;
 
1147
  embedding= ptr->embedding;
 
1148
  nested_join= ptr->nested_join;
1086
1149
  if (nested_join->join_list.elements == 1)
1087
1150
  {
1088
1151
    TableList *embedded= nested_join->join_list.head();
1089
1152
    join_list->pop();
1090
 
    embedded->setJoinList(join_list);
1091
 
    embedded->setEmbedding(embedding);
 
1153
    embedded->join_list= join_list;
 
1154
    embedded->embedding= embedding;
1092
1155
    join_list->push_front(embedded);
1093
1156
    ptr= embedded;
1094
1157
  }
1121
1184
  List<TableList> *embedded_list;
1122
1185
 
1123
1186
  if (!(ptr= (TableList*) session->calloc(ALIGN_SIZE(sizeof(TableList))+
1124
 
                                          sizeof(nested_join_st))))
 
1187
                                       sizeof(nested_join_st))))
1125
1188
    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);
 
1189
  nested_join= ptr->nested_join=
 
1190
    ((nested_join_st*) ((unsigned char*) ptr + ALIGN_SIZE(sizeof(TableList))));
 
1191
 
 
1192
  ptr->embedding= embedding;
 
1193
  ptr->join_list= join_list;
1130
1194
  ptr->alias= (char*) "(nest_last_join)";
1131
1195
  embedded_list= &nested_join->join_list;
1132
1196
  embedded_list->empty();
1134
1198
  for (uint32_t i=0; i < 2; i++)
1135
1199
  {
1136
1200
    TableList *table= join_list->pop();
1137
 
    table->setJoinList(embedded_list);
1138
 
    table->setEmbedding(ptr);
 
1201
    table->join_list= embedded_list;
 
1202
    table->embedding= ptr;
1139
1203
    embedded_list->push_back(table);
1140
1204
    if (table->natural_join)
1141
1205
    {
1171
1235
void Select_Lex::add_joined_table(TableList *table)
1172
1236
{
1173
1237
  join_list->push_front(table);
1174
 
  table->setJoinList(join_list);
1175
 
  table->setEmbedding(embedding);
 
1238
  table->join_list= join_list;
 
1239
  table->embedding= embedding;
1176
1240
}
1177
1241
 
1178
1242
 
1232
1296
 
1233
1297
void Select_Lex::set_lock_for_tables(thr_lock_type lock_type)
1234
1298
{
 
1299
  bool for_update= lock_type >= TL_READ_NO_INSERT;
 
1300
 
1235
1301
  for (TableList *tables= (TableList*) table_list.first;
1236
1302
       tables;
1237
1303
       tables= tables->next_local)
1238
1304
  {
1239
1305
    tables->lock_type= lock_type;
 
1306
    tables->updating=  for_update;
1240
1307
  }
 
1308
  return;
1241
1309
}
1242
1310
 
1243
1311
 
1248
1316
    This object is created for any union construct containing a union
1249
1317
    operation and also for any single select union construct of the form
1250
1318
    @verbatim
1251
 
    (SELECT ... ORDER BY order_list [LIMIT n]) ORDER BY ...
 
1319
    (SELECT ... order_st BY order_list [LIMIT n]) order_st BY ...
1252
1320
    @endvarbatim
1253
1321
    or of the form
1254
1322
    @varbatim
1255
 
    (SELECT ... ORDER BY LIMIT n) ORDER BY ...
 
1323
    (SELECT ... order_st BY LIMIT n) order_st BY ...
1256
1324
    @endvarbatim
1257
1325
 
1258
1326
  @param session_arg               thread handle
1283
1351
  fake_select_lex->select_limit= 0;
1284
1352
 
1285
1353
  fake_select_lex->context.outer_context=first_sl->context.outer_context;
1286
 
  /* allow item list resolving in fake select for ORDER BY */
 
1354
  /* allow item list resolving in fake select for order_st BY */
1287
1355
  fake_select_lex->context.resolve_in_select_list= true;
1288
1356
  fake_select_lex->context.select_lex= fake_select_lex;
1289
1357
 
1291
1359
  {
1292
1360
    /*
1293
1361
      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]
 
1362
      (SELECT ... order_st BY list [LIMIT n]) order_st BY order_list [LIMIT m],
 
1363
      (SELECT ... LIMIT n) order_st BY order_list [LIMIT m]
1296
1364
      just before the parser starts processing order_list
1297
1365
    */
1298
1366
    global_parameters= fake_select_lex;
1415
1483
 
1416
1484
 
1417
1485
/**
 
1486
  kill on thread.
 
1487
 
 
1488
  @param session                        Thread class
 
1489
  @param id                     Thread id
 
1490
  @param only_kill_query        Should it kill the query or the connection
 
1491
 
 
1492
  @note
 
1493
    This is written such that we have a short lock on LOCK_thread_count
 
1494
*/
 
1495
 
 
1496
static unsigned int
 
1497
kill_one_thread(Session *, ulong id, bool only_kill_query)
 
1498
{
 
1499
  Session *tmp= NULL;
 
1500
  uint32_t error=ER_NO_SUCH_THREAD;
 
1501
  pthread_mutex_lock(&LOCK_thread_count); // For unlink from list
 
1502
  
 
1503
  for( vector<Session*>::iterator it= getSessionList().begin(); it != getSessionList().end(); ++it )
 
1504
  {
 
1505
    if ((*it)->thread_id == id)
 
1506
    {
 
1507
      tmp= *it;
 
1508
      pthread_mutex_lock(&tmp->LOCK_delete);    // Lock from delete
 
1509
      break;
 
1510
    }
 
1511
  }
 
1512
  pthread_mutex_unlock(&LOCK_thread_count);
 
1513
  if (tmp)
 
1514
  {
 
1515
    tmp->awake(only_kill_query ? Session::KILL_QUERY : Session::KILL_CONNECTION);
 
1516
    error=0;
 
1517
    pthread_mutex_unlock(&tmp->LOCK_delete);
 
1518
  }
 
1519
  return(error);
 
1520
}
 
1521
 
 
1522
 
 
1523
/*
 
1524
  kills a thread and sends response
 
1525
 
 
1526
  SYNOPSIS
 
1527
    sql_kill()
 
1528
    session                     Thread class
 
1529
    id                  Thread id
 
1530
    only_kill_query     Should it kill the query or the connection
 
1531
*/
 
1532
 
 
1533
void sql_kill(Session *session, ulong id, bool only_kill_query)
 
1534
{
 
1535
  uint32_t error;
 
1536
  if (!(error= kill_one_thread(session, id, only_kill_query)))
 
1537
    session->my_ok();
 
1538
  else
 
1539
    my_error(error, MYF(0), id);
 
1540
}
 
1541
 
 
1542
 
 
1543
/**
1418
1544
  Check if the select is a simple select (not an union).
1419
1545
 
1420
1546
  @retval
1542
1668
 
1543
1669
 
1544
1670
/**
 
1671
  CREATE TABLE query pre-check.
 
1672
 
 
1673
  @param session                        Thread handler
 
1674
  @param tables         Global table list
 
1675
  @param create_table           Table which will be created
 
1676
 
 
1677
  @retval
 
1678
    false   OK
 
1679
  @retval
 
1680
    true   Error
 
1681
*/
 
1682
 
 
1683
bool create_table_precheck(TableIdentifier &identifier)
 
1684
{
 
1685
  if (strcmp(identifier.getDBName(), "information_schema") == 0)
 
1686
  {
 
1687
    my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), "", "", INFORMATION_SCHEMA_NAME.c_str());
 
1688
    return true;
 
1689
  }
 
1690
 
 
1691
  return false;
 
1692
}
 
1693
 
 
1694
 
 
1695
/**
1545
1696
  negate given expression.
1546
1697
 
1547
1698
  @param session  thread handler
1649
1800
  return true;
1650
1801
}
1651
1802
 
 
1803
extern int DRIZZLEparse(void *session); // from sql_yacc.cc
 
1804
 
1652
1805
 
1653
1806
/**
1654
1807
  This is a wrapper of DRIZZLEparse(). All the code should call parse_sql()
1666
1819
{
1667
1820
  assert(session->m_lip == NULL);
1668
1821
 
1669
 
  DRIZZLE_QUERY_PARSE_START(session->getQueryString()->c_str());
 
1822
  DRIZZLE_QUERY_PARSE_START(session->query);
1670
1823
 
1671
1824
  /* Set Lex_input_stream. */
1672
1825
 
1694
1847
/**
1695
1848
  @} (end of group Runtime_Environment)
1696
1849
*/
1697
 
 
1698
 
} /* namespace drizzled */