~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_parse.cc

  • Committer: Brian Aker
  • Date: 2010-11-08 18:24:58 UTC
  • mto: (1921.1.1 trunk)
  • mto: This revision was merged to the branch mainline in revision 1916.
  • Revision ID: brian@tangent.org-20101108182458-twv4hyix43ojno80
Merge in changes such that lock is now broken out into its own directory.

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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
 
14
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
15
15
 
16
16
#include "config.h"
17
17
 
44
44
 
45
45
#include "drizzled/plugin/logging.h"
46
46
#include "drizzled/plugin/query_rewrite.h"
 
47
#include "drizzled/plugin/query_cache.h"
47
48
#include "drizzled/plugin/authorization.h"
48
49
#include "drizzled/optimizer/explain_plan.h"
49
50
#include "drizzled/pthread_globals.h"
 
51
#include "drizzled/plugin/event_observer.h"
50
52
 
51
53
#include <limits.h>
52
54
 
182
184
    break;
183
185
  /* Increase id and count all other statements. */
184
186
  default:
185
 
    statistic_increment(session->status_var.questions, &LOCK_status);
 
187
    session->status_var.questions++;
186
188
    query_id.next();
187
189
  }
188
190
 
189
191
  /* TODO: set session->lex->sql_command to SQLCOM_END here */
190
192
 
191
193
  plugin::Logging::preDo(session);
 
194
  if (unlikely(plugin::EventObserver::beforeStatement(*session)))
 
195
  {
 
196
    // We should do something about an error...
 
197
  }
192
198
 
193
199
  session->server_status&=
194
200
           ~(SERVER_QUERY_NO_INDEX_USED | SERVER_QUERY_NO_GOOD_INDEX_USED);
195
201
  switch (command) {
196
202
  case COM_INIT_DB:
197
203
  {
198
 
    status_var_increment(session->status_var.com_stat[SQLCOM_CHANGE_DB]);
199
204
    if (packet_length == 0)
200
205
    {
201
206
      my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
232
237
    break;
233
238
  case COM_SHUTDOWN:
234
239
  {
235
 
    status_var_increment(session->status_var.com_other);
 
240
    session->status_var.com_other++;
236
241
    session->my_eof();
237
242
    session->close_thread_tables();                     // Free before kill
238
243
    kill_drizzle();
240
245
    break;
241
246
  }
242
247
  case COM_PING:
243
 
    status_var_increment(session->status_var.com_other);
 
248
    session->status_var.com_other++;
244
249
    session->my_ok();                           // Tell client we are alive
245
250
    break;
246
251
  case COM_SLEEP:
254
259
  /* If commit fails, we should be able to reset the OK status. */
255
260
  session->main_da.can_overwrite_status= true;
256
261
  TransactionServices &transaction_services= TransactionServices::singleton();
257
 
  transaction_services.ha_autocommit_or_rollback(session, session->is_error());
 
262
  transaction_services.autocommitOrRollback(session, session->is_error());
258
263
  session->main_da.can_overwrite_status= false;
259
264
 
260
265
  session->transaction.stmt.reset();
269
274
  if (session->killed == Session::KILL_QUERY || session->killed == Session::KILL_BAD_DATA)
270
275
  {
271
276
    session->killed= Session::NOT_KILLED;
272
 
    session->mysys_var->abort= 0;
 
277
    session->setAbort(false);
273
278
  }
274
279
 
275
280
  /* Can not be true, but do not take chances in production. */
307
312
  session->close_thread_tables();
308
313
 
309
314
  plugin::Logging::postDo(session);
 
315
  if (unlikely(plugin::EventObserver::afterStatement(*session)))
 
316
  {
 
317
    // We should do something about an error...
 
318
  }
310
319
 
311
320
  /* Store temp state for processlist */
312
321
  session->set_proc_info("cleaning up");
315
324
  session->query.clear();
316
325
 
317
326
  session->set_proc_info(NULL);
318
 
  free_root(session->mem_root,MYF(memory::KEEP_PREALLOC));
 
327
  session->mem_root->free_root(MYF(memory::KEEP_PREALLOC));
319
328
 
320
329
  if (DRIZZLE_QUERY_DONE_ENABLED() || DRIZZLE_COMMAND_DONE_ENABLED())
321
330
  {
359
368
                           const string& schema_table_name)
360
369
{
361
370
  LEX_STRING db, table;
 
371
  bitset<NUM_OF_TABLE_OPTIONS> table_options;
362
372
  /*
363
373
     We have to make non const db_name & table_name
364
374
     because of lower_case_table_names
367
377
  session->make_lex_string(&table, schema_table_name, false);
368
378
 
369
379
  if (! sel->add_table_to_list(session, new Table_ident(db, table),
370
 
                               NULL, 0, TL_READ))
 
380
                               NULL, table_options, TL_READ))
371
381
  {
372
382
    return true;
373
383
  }
473
483
    drizzle_reset_errors(session, 0);
474
484
  }
475
485
 
476
 
  status_var_increment(session->status_var.com_stat[lex->sql_command]);
477
 
 
478
486
  assert(session->transaction.stmt.hasModifiedNonTransData() == false);
479
487
 
480
488
  /* now we are ready to execute the statement */
481
489
  res= lex->statement->execute();
482
 
 
483
490
  session->set_proc_info("query end");
484
 
 
485
491
  /*
486
492
    The return value for ROW_COUNT() is "implementation dependent" if the
487
493
    statement is not DELETE, INSERT or UPDATE, but -1 is what JDBC and ODBC
495
501
 
496
502
  return (res || session->is_error());
497
503
}
498
 
 
499
504
bool execute_sqlcom_select(Session *session, TableList *all_tables)
500
505
{
501
506
  LEX   *lex= session->lex;
543
548
    {
544
549
      if (!result && !(result= new select_send()))
545
550
        return true;
 
551
 
 
552
      /* Init the Query Cache plugin */
 
553
      plugin::QueryCache::prepareResultset(session); 
546
554
      res= handle_select(session, lex, result, 0);
 
555
      /* Send the Resultset to the cache */
 
556
      plugin::QueryCache::setResultset(session); 
 
557
 
547
558
      if (result != lex->result)
548
559
        delete result;
549
560
    }
715
726
 
716
727
void mysql_parse(Session *session, const char *inBuf, uint32_t length)
717
728
{
718
 
  lex_start(session);
 
729
  uint64_t start_time= my_getsystime();
 
730
  session->lex->start(session);
719
731
  session->reset_for_next_command();
720
 
 
 
732
  /* Check if the Query is Cached if and return true if yes
 
733
   * TODO the plugin has to make sure that the query is cacheble
 
734
   * by setting the query_safe_cache param to TRUE
 
735
   */
 
736
  bool res= true;
 
737
  if (plugin::QueryCache::isCached(session))
 
738
  {
 
739
    res= plugin::QueryCache::sendCachedResultset(session);
 
740
  }
 
741
  if (not res)
 
742
  {
 
743
    return;
 
744
  }
721
745
  LEX *lex= session->lex;
722
 
 
723
746
  Lex_input_stream lip(session, inBuf, length);
724
 
 
725
747
  bool err= parse_sql(session, &lip);
726
 
 
727
748
  if (!err)
728
749
  {
729
750
    {
732
753
        DRIZZLE_QUERY_EXEC_START(session->query.c_str(),
733
754
                                 session->thread_id,
734
755
                                 const_cast<const char *>(session->db.empty() ? "" : session->db.c_str()));
 
756
        // Implement Views here --Brian
735
757
        /* Actually execute the query */
736
 
        mysql_execute_command(session);
 
758
        try 
 
759
        {
 
760
          mysql_execute_command(session);
 
761
        }
 
762
        catch (...)
 
763
        {
 
764
          // Just try to catch any random failures that could have come
 
765
          // during execution.
 
766
        }
737
767
        DRIZZLE_QUERY_EXEC_DONE(0);
738
768
      }
739
769
    }
742
772
  {
743
773
    assert(session->is_error());
744
774
  }
745
 
 
746
775
  lex->unit.cleanup();
747
776
  session->set_proc_info("freeing items");
748
777
  session->end_statement();
749
778
  session->cleanup_after_query();
750
 
 
751
 
  return;
 
779
  session->status_var.execution_time_nsec+= my_getsystime() - start_time;
752
780
}
753
781
 
754
782
 
876
904
*/
877
905
 
878
906
TableList *Select_Lex::add_table_to_list(Session *session,
879
 
                                             Table_ident *table,
880
 
                                             LEX_STRING *alias,
881
 
                                             uint32_t table_options,
882
 
                                             thr_lock_type lock_type,
883
 
                                             List<Index_hint> *index_hints_arg,
884
 
                                             LEX_STRING *option)
 
907
                                                             Table_ident *table,
 
908
                                                             LEX_STRING *alias,
 
909
                                                             const bitset<NUM_OF_TABLE_OPTIONS>& table_options,
 
910
                                                             thr_lock_type lock_type,
 
911
                                                             List<Index_hint> *index_hints_arg,
 
912
                                         LEX_STRING *option)
885
913
{
886
 
  register TableList *ptr;
 
914
  TableList *ptr;
887
915
  TableList *previous_table_ref; /* The table preceding the current one. */
888
916
  char *alias_str;
889
917
  LEX *lex= session->lex;
891
919
  if (!table)
892
920
    return NULL;                                // End of memory
893
921
  alias_str= alias ? alias->str : table->table.str;
894
 
  if (!test(table_options & TL_OPTION_ALIAS) &&
 
922
  if (! table_options.test(TL_OPTION_ALIAS) &&
895
923
      check_table_name(table->table.str, table->table.length))
896
924
  {
897
925
    my_error(ER_WRONG_TABLE_NAME, MYF(0), table->table.str);
902
930
  {
903
931
    my_casedn_str(files_charset_info, table->db.str);
904
932
 
905
 
    SchemaIdentifier schema_identifier(string(table->db.str, table->db.length));
906
 
    if (not check_db_name(schema_identifier))
 
933
    SchemaIdentifier schema_identifier(string(table->db.str));
 
934
    if (not check_db_name(session, schema_identifier))
907
935
    {
908
936
 
909
937
      my_error(ER_WRONG_DB_NAME, MYF(0), table->db.str);
924
952
  }
925
953
  if (!(ptr = (TableList *) session->calloc(sizeof(TableList))))
926
954
    return NULL;
 
955
 
927
956
  if (table->db.str)
928
957
  {
929
 
    ptr->is_fqtn= true;
930
 
    ptr->db= table->db.str;
 
958
    ptr->setIsFqtn(true);
 
959
    ptr->setSchemaName(table->db.str);
931
960
    ptr->db_length= table->db.length;
932
961
  }
933
 
  else if (lex->copy_db_to(&ptr->db, &ptr->db_length))
 
962
  else if (lex->copy_db_to(ptr->getSchemaNamePtr(), &ptr->db_length))
934
963
    return NULL;
935
964
  else
936
 
    ptr->is_fqtn= false;
 
965
    ptr->setIsFqtn(false);
937
966
 
938
967
  ptr->alias= alias_str;
939
 
  ptr->is_alias= alias ? true : false;
 
968
  ptr->setIsAlias(alias ? true : false);
940
969
  if (table->table.length)
941
970
    table->table.length= my_casedn_str(files_charset_info, table->table.str);
942
 
  ptr->table_name=table->table.str;
 
971
  ptr->setTableName(table->table.str);
943
972
  ptr->table_name_length=table->table.length;
944
973
  ptr->lock_type=   lock_type;
945
 
  ptr->force_index= test(table_options & TL_OPTION_FORCE_INDEX);
946
 
  ptr->ignore_leaves= test(table_options & TL_OPTION_IGNORE_LEAVES);
 
974
  ptr->force_index= table_options.test(TL_OPTION_FORCE_INDEX);
 
975
  ptr->ignore_leaves= table_options.test(TL_OPTION_IGNORE_LEAVES);
947
976
  ptr->derived=     table->sel;
948
977
  ptr->select_lex=  lex->current_select;
949
978
  ptr->index_hints= index_hints_arg;
957
986
         tables=tables->next_local)
958
987
    {
959
988
      if (!my_strcasecmp(table_alias_charset, alias_str, tables->alias) &&
960
 
          !strcasecmp(ptr->db, tables->db))
 
989
          !strcasecmp(ptr->getSchemaName(), tables->getSchemaName()))
961
990
      {
962
991
        my_error(ER_NONUNIQ_TABLE, MYF(0), alias_str);
963
992
        return NULL;
1026
1055
  if (!(ptr= (TableList*) session->calloc(ALIGN_SIZE(sizeof(TableList))+
1027
1056
                                       sizeof(nested_join_st))))
1028
1057
    return true;
1029
 
  nested_join= ptr->nested_join=
1030
 
    ((nested_join_st*) ((unsigned char*) ptr + ALIGN_SIZE(sizeof(TableList))));
1031
 
 
 
1058
  ptr->setNestedJoin(((nested_join_st*) ((unsigned char*) ptr + ALIGN_SIZE(sizeof(TableList)))));
 
1059
  nested_join= ptr->getNestedJoin();
1032
1060
  join_list->push_front(ptr);
1033
 
  ptr->embedding= embedding;
1034
 
  ptr->join_list= join_list;
 
1061
  ptr->setEmbedding(embedding);
 
1062
  ptr->setJoinList(join_list);
1035
1063
  ptr->alias= (char*) "(nested_join)";
1036
1064
  embedding= ptr;
1037
1065
  join_list= &nested_join->join_list;
1061
1089
 
1062
1090
  assert(embedding);
1063
1091
  ptr= embedding;
1064
 
  join_list= ptr->join_list;
1065
 
  embedding= ptr->embedding;
1066
 
  nested_join= ptr->nested_join;
 
1092
  join_list= ptr->getJoinList();
 
1093
  embedding= ptr->getEmbedding();
 
1094
  nested_join= ptr->getNestedJoin();
1067
1095
  if (nested_join->join_list.elements == 1)
1068
1096
  {
1069
1097
    TableList *embedded= nested_join->join_list.head();
1070
1098
    join_list->pop();
1071
 
    embedded->join_list= join_list;
1072
 
    embedded->embedding= embedding;
 
1099
    embedded->setJoinList(join_list);
 
1100
    embedded->setEmbedding(embedding);
1073
1101
    join_list->push_front(embedded);
1074
1102
    ptr= embedded;
1075
1103
  }
1102
1130
  List<TableList> *embedded_list;
1103
1131
 
1104
1132
  if (!(ptr= (TableList*) session->calloc(ALIGN_SIZE(sizeof(TableList))+
1105
 
                                       sizeof(nested_join_st))))
 
1133
                                          sizeof(nested_join_st))))
1106
1134
    return NULL;
1107
 
  nested_join= ptr->nested_join=
1108
 
    ((nested_join_st*) ((unsigned char*) ptr + ALIGN_SIZE(sizeof(TableList))));
1109
 
 
1110
 
  ptr->embedding= embedding;
1111
 
  ptr->join_list= join_list;
 
1135
  ptr->setNestedJoin(((nested_join_st*) ((unsigned char*) ptr + ALIGN_SIZE(sizeof(TableList)))));
 
1136
  nested_join= ptr->getNestedJoin();
 
1137
  ptr->setEmbedding(embedding);
 
1138
  ptr->setJoinList(join_list);
1112
1139
  ptr->alias= (char*) "(nest_last_join)";
1113
1140
  embedded_list= &nested_join->join_list;
1114
1141
  embedded_list->empty();
1116
1143
  for (uint32_t i=0; i < 2; i++)
1117
1144
  {
1118
1145
    TableList *table= join_list->pop();
1119
 
    table->join_list= embedded_list;
1120
 
    table->embedding= ptr;
 
1146
    table->setJoinList(embedded_list);
 
1147
    table->setEmbedding(ptr);
1121
1148
    embedded_list->push_back(table);
1122
1149
    if (table->natural_join)
1123
1150
    {
1153
1180
void Select_Lex::add_joined_table(TableList *table)
1154
1181
{
1155
1182
  join_list->push_front(table);
1156
 
  table->join_list= join_list;
1157
 
  table->embedding= embedding;
 
1183
  table->setJoinList(join_list);
 
1184
  table->setEmbedding(embedding);
1158
1185
}
1159
1186
 
1160
1187
 
1408
1435
*/
1409
1436
 
1410
1437
static unsigned int
1411
 
kill_one_thread(Session *, ulong id, bool only_kill_query)
 
1438
kill_one_thread(Session *, session_id_t id, bool only_kill_query)
1412
1439
{
1413
1440
  Session *tmp= NULL;
1414
1441
  uint32_t error= ER_NO_SUCH_THREAD;
1415
 
  pthread_mutex_lock(&LOCK_thread_count); // For unlink from list
1416
1442
  
1417
 
  for (SessionList::iterator it= getSessionList().begin(); it != getSessionList().end(); ++it )
1418
1443
  {
1419
 
    if ((*it)->thread_id == id)
 
1444
    boost::mutex::scoped_lock scoped(LOCK_thread_count);
 
1445
    for (SessionList::iterator it= getSessionList().begin(); it != getSessionList().end(); ++it )
1420
1446
    {
1421
 
      tmp= *it;
1422
 
      pthread_mutex_lock(&tmp->LOCK_delete);    // Lock from delete
1423
 
      break;
 
1447
      if ((*it)->thread_id == id)
 
1448
      {
 
1449
        tmp= *it;
 
1450
        tmp->lockForDelete();
 
1451
        break;
 
1452
      }
1424
1453
    }
1425
1454
  }
1426
 
  pthread_mutex_unlock(&LOCK_thread_count);
 
1455
 
1427
1456
  if (tmp)
1428
1457
  {
1429
1458
 
1433
1462
      error= 0;
1434
1463
    }
1435
1464
 
1436
 
    pthread_mutex_unlock(&tmp->LOCK_delete);
 
1465
    tmp->unlockForDelete();
1437
1466
  }
1438
1467
  return(error);
1439
1468
}
1449
1478
    only_kill_query     Should it kill the query or the connection
1450
1479
*/
1451
1480
 
1452
 
void sql_kill(Session *session, ulong id, bool only_kill_query)
 
1481
void sql_kill(Session *session, int64_t id, bool only_kill_query)
1453
1482
{
1454
1483
  uint32_t error;
1455
1484
  if (!(error= kill_one_thread(session, id, only_kill_query)))