~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_parse.cc

  • Committer: Monty Taylor
  • Date: 2010-10-13 17:53:36 UTC
  • mto: This revision was merged to the branch mainline in revision 1845.
  • Revision ID: mordred@inaugust.com-20101013175336-amzhjftgztblvua5
Updated pandora-build files to version 0.161

Show diffs side-by-side

added added

removed removed

Lines of Context:
39
39
#include <drizzled/statement.h>
40
40
#include <drizzled/statement/alter_table.h>
41
41
#include "drizzled/probes.h"
42
 
#include "drizzled/session/cache.h"
 
42
#include "drizzled/session_list.h"
43
43
#include "drizzled/global_charset_info.h"
44
44
 
45
45
#include "drizzled/plugin/logging.h"
54
54
 
55
55
#include <bitset>
56
56
#include <algorithm>
57
 
#include <boost/date_time.hpp>
 
57
 
58
58
#include "drizzled/internal/my_sys.h"
59
59
 
60
60
using namespace std;
170
170
  bool error= 0;
171
171
  Query_id &query_id= Query_id::get_query_id();
172
172
 
173
 
  DRIZZLE_COMMAND_START(session->thread_id, command);
 
173
  DRIZZLE_COMMAND_START(session->thread_id,
 
174
                        command);
174
175
 
175
176
  session->command= command;
176
177
  session->lex->sql_command= SQLCOM_END; /* to avoid confusing VIEW detectors */
218
219
  }
219
220
  case COM_QUERY:
220
221
  {
221
 
    if (not session->readAndStoreQuery(packet, packet_length))
 
222
    if (! session->readAndStoreQuery(packet, packet_length))
222
223
      break;                                    // fatal error is set
223
 
    DRIZZLE_QUERY_START(session->getQueryString()->c_str(),
 
224
    DRIZZLE_QUERY_START(session->query.c_str(),
224
225
                        session->thread_id,
225
 
                        const_cast<const char *>(session->schema()->c_str()));
 
226
                        const_cast<const char *>(session->db.empty() ? "" : session->db.c_str()));
226
227
 
227
 
    mysql_parse(session, session->getQueryString()->c_str(), session->getQueryString()->length());
 
228
    plugin::QueryRewriter::rewriteQuery(session->db, session->query);
 
229
    mysql_parse(session, session->query.c_str(), session->query.length());
228
230
 
229
231
    break;
230
232
  }
269
271
    if (! session->main_da.is_set())
270
272
      session->send_kill_message();
271
273
  }
272
 
  if (session->getKilled() == Session::KILL_QUERY || session->getKilled() == Session::KILL_BAD_DATA)
 
274
  if (session->killed == Session::KILL_QUERY || session->killed == Session::KILL_BAD_DATA)
273
275
  {
274
 
    session->setKilled(Session::NOT_KILLED);
 
276
    session->killed= Session::NOT_KILLED;
275
277
    session->setAbort(false);
276
278
  }
277
279
 
318
320
  /* Store temp state for processlist */
319
321
  session->set_proc_info("cleaning up");
320
322
  session->command= COM_SLEEP;
321
 
  session->resetQueryString();
 
323
  memset(session->process_list_info, 0, PROCESS_LIST_WIDTH);
 
324
  session->query.clear();
322
325
 
323
326
  session->set_proc_info(NULL);
324
327
  session->mem_root->free_root(MYF(memory::KEEP_PREALLOC));
365
368
                           const string& schema_table_name)
366
369
{
367
370
  LEX_STRING db, table;
368
 
  bitset<NUM_OF_TABLE_OPTIONS> table_options;
369
371
  /*
370
372
     We have to make non const db_name & table_name
371
373
     because of lower_case_table_names
374
376
  session->make_lex_string(&table, schema_table_name, false);
375
377
 
376
378
  if (! sel->add_table_to_list(session, new Table_ident(db, table),
377
 
                               NULL, table_options, TL_READ))
 
379
                               NULL, 0, TL_READ))
378
380
  {
379
381
    return true;
380
382
  }
429
431
    true        Error
430
432
*/
431
433
 
432
 
static int mysql_execute_command(Session *session)
 
434
static int
 
435
mysql_execute_command(Session *session)
433
436
{
434
437
  bool res= false;
435
438
  LEX  *lex= session->lex;
437
440
  Select_Lex *select_lex= &lex->select_lex;
438
441
  /* list of all tables in query */
439
442
  TableList *all_tables;
 
443
  /* A peek into the query string */
 
444
  size_t proc_info_len= session->query.length() > PROCESS_LIST_WIDTH ?
 
445
                        PROCESS_LIST_WIDTH : session->query.length();
 
446
 
 
447
  memcpy(session->process_list_info, session->query.c_str(), proc_info_len);
 
448
  session->process_list_info[proc_info_len]= '\0';
440
449
 
441
450
  /*
442
451
    In many cases first table of main Select_Lex have special meaning =>
716
725
 
717
726
void mysql_parse(Session *session, const char *inBuf, uint32_t length)
718
727
{
719
 
  boost::posix_time::ptime start_time=boost::posix_time::microsec_clock::local_time();
720
 
  session->lex->start(session);
721
 
 
 
728
  uint64_t start_time= my_getsystime();
 
729
  lex_start(session);
722
730
  session->reset_for_next_command();
723
731
  /* Check if the Query is Cached if and return true if yes
724
732
   * TODO the plugin has to make sure that the query is cacheble
739
747
  if (!err)
740
748
  {
741
749
    {
742
 
      if (not session->is_error())
 
750
      if (! session->is_error())
743
751
      {
744
 
        DRIZZLE_QUERY_EXEC_START(session->getQueryString()->c_str(),
 
752
        DRIZZLE_QUERY_EXEC_START(session->query.c_str(),
745
753
                                 session->thread_id,
746
 
                                 const_cast<const char *>(session->schema()->c_str()));
 
754
                                 const_cast<const char *>(session->db.empty() ? "" : session->db.c_str()));
747
755
        // Implement Views here --Brian
748
756
        /* Actually execute the query */
749
757
        try 
754
762
        {
755
763
          // Just try to catch any random failures that could have come
756
764
          // during execution.
757
 
          unireg_abort(1);
758
765
        }
759
766
        DRIZZLE_QUERY_EXEC_DONE(0);
760
767
      }
768
775
  session->set_proc_info("freeing items");
769
776
  session->end_statement();
770
777
  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();
 
778
  session->status_var.execution_time_nsec+= my_getsystime() - start_time;
773
779
}
774
780
 
775
781
 
897
903
*/
898
904
 
899
905
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)
 
906
                                             Table_ident *table,
 
907
                                             LEX_STRING *alias,
 
908
                                             uint32_t table_options,
 
909
                                             thr_lock_type lock_type,
 
910
                                             List<Index_hint> *index_hints_arg,
 
911
                                             LEX_STRING *option)
906
912
{
907
 
  TableList *ptr;
 
913
  register TableList *ptr;
908
914
  TableList *previous_table_ref; /* The table preceding the current one. */
909
915
  char *alias_str;
910
916
  LEX *lex= session->lex;
912
918
  if (!table)
913
919
    return NULL;                                // End of memory
914
920
  alias_str= alias ? alias->str : table->table.str;
915
 
  if (! table_options.test(TL_OPTION_ALIAS) &&
 
921
  if (!test(table_options & TL_OPTION_ALIAS) &&
916
922
      check_table_name(table->table.str, table->table.length))
917
923
  {
918
924
    my_error(ER_WRONG_TABLE_NAME, MYF(0), table->table.str);
949
955
  if (table->db.str)
950
956
  {
951
957
    ptr->setIsFqtn(true);
952
 
    ptr->setSchemaName(table->db.str);
 
958
    ptr->db= table->db.str;
953
959
    ptr->db_length= table->db.length;
954
960
  }
955
 
  else if (lex->copy_db_to(ptr->getSchemaNamePtr(), &ptr->db_length))
 
961
  else if (lex->copy_db_to(&ptr->db, &ptr->db_length))
956
962
    return NULL;
957
963
  else
958
964
    ptr->setIsFqtn(false);
959
965
 
960
966
  ptr->alias= alias_str;
961
967
  ptr->setIsAlias(alias ? true : false);
962
 
  ptr->setTableName(table->table.str);
 
968
  if (table->table.length)
 
969
    table->table.length= my_casedn_str(files_charset_info, table->table.str);
 
970
  ptr->table_name=table->table.str;
963
971
  ptr->table_name_length=table->table.length;
964
972
  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);
 
973
  ptr->force_index= test(table_options & TL_OPTION_FORCE_INDEX);
 
974
  ptr->ignore_leaves= test(table_options & TL_OPTION_IGNORE_LEAVES);
967
975
  ptr->derived=     table->sel;
968
976
  ptr->select_lex=  lex->current_select;
969
977
  ptr->index_hints= index_hints_arg;
977
985
         tables=tables->next_local)
978
986
    {
979
987
      if (!my_strcasecmp(table_alias_charset, alias_str, tables->alias) &&
980
 
          !strcasecmp(ptr->getSchemaName(), tables->getSchemaName()))
 
988
          !strcasecmp(ptr->db, tables->db))
981
989
      {
982
990
        my_error(ER_NONUNIQ_TABLE, MYF(0), alias_str);
983
991
        return NULL;
1415
1423
 
1416
1424
 
1417
1425
/**
 
1426
  kill on thread.
 
1427
 
 
1428
  @param session                        Thread class
 
1429
  @param id                     Thread id
 
1430
  @param only_kill_query        Should it kill the query or the connection
 
1431
 
 
1432
  @note
 
1433
    This is written such that we have a short lock on LOCK_thread_count
 
1434
*/
 
1435
 
 
1436
static unsigned int
 
1437
kill_one_thread(Session *, ulong id, bool only_kill_query)
 
1438
{
 
1439
  Session *tmp= NULL;
 
1440
  uint32_t error= ER_NO_SUCH_THREAD;
 
1441
  LOCK_thread_count.lock(); // For unlink from list
 
1442
  
 
1443
  for (SessionList::iterator it= getSessionList().begin(); it != getSessionList().end(); ++it )
 
1444
  {
 
1445
    if ((*it)->thread_id == id)
 
1446
    {
 
1447
      tmp= *it;
 
1448
      tmp->lockForDelete();
 
1449
      break;
 
1450
    }
 
1451
  }
 
1452
  LOCK_thread_count.unlock();
 
1453
  if (tmp)
 
1454
  {
 
1455
 
 
1456
    if (tmp->isViewable())
 
1457
    {
 
1458
      tmp->awake(only_kill_query ? Session::KILL_QUERY : Session::KILL_CONNECTION);
 
1459
      error= 0;
 
1460
    }
 
1461
 
 
1462
    tmp->unlockForDelete();
 
1463
  }
 
1464
  return(error);
 
1465
}
 
1466
 
 
1467
 
 
1468
/*
 
1469
  kills a thread and sends response
 
1470
 
 
1471
  SYNOPSIS
 
1472
    sql_kill()
 
1473
    session                     Thread class
 
1474
    id                  Thread id
 
1475
    only_kill_query     Should it kill the query or the connection
 
1476
*/
 
1477
 
 
1478
void sql_kill(Session *session, ulong id, bool only_kill_query)
 
1479
{
 
1480
  uint32_t error;
 
1481
  if (!(error= kill_one_thread(session, id, only_kill_query)))
 
1482
    session->my_ok();
 
1483
  else
 
1484
    my_error(error, MYF(0), id);
 
1485
}
 
1486
 
 
1487
 
 
1488
/**
1418
1489
  Check if the select is a simple select (not an union).
1419
1490
 
1420
1491
  @retval
1542
1613
 
1543
1614
 
1544
1615
/**
 
1616
  CREATE TABLE query pre-check.
 
1617
 
 
1618
  @param session                        Thread handler
 
1619
  @param tables         Global table list
 
1620
  @param create_table           Table which will be created
 
1621
 
 
1622
  @retval
 
1623
    false   OK
 
1624
  @retval
 
1625
    true   Error
 
1626
*/
 
1627
 
 
1628
bool create_table_precheck(TableIdentifier &identifier)
 
1629
{
 
1630
  if (not plugin::StorageEngine::canCreateTable(identifier))
 
1631
  {
 
1632
    my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), "", "", identifier.getSchemaName().c_str());
 
1633
    return true;
 
1634
  }
 
1635
 
 
1636
  if (not plugin::StorageEngine::doesSchemaExist(identifier))
 
1637
  {
 
1638
    my_error(ER_BAD_DB_ERROR, MYF(0), identifier.getSchemaName().c_str());
 
1639
    return true;
 
1640
  }
 
1641
 
 
1642
  return false;
 
1643
}
 
1644
 
 
1645
 
 
1646
/**
1545
1647
  negate given expression.
1546
1648
 
1547
1649
  @param session  thread handler
1666
1768
{
1667
1769
  assert(session->m_lip == NULL);
1668
1770
 
1669
 
  DRIZZLE_QUERY_PARSE_START(session->getQueryString()->c_str());
 
1771
  DRIZZLE_QUERY_PARSE_START(session->query.c_str());
1670
1772
 
1671
1773
  /* Set Lex_input_stream. */
1672
1774