~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/session.cc

Merged Eric from lp:~eday/drizzle/eday-merge

Show diffs side-by-side

added added

removed removed

Lines of Context:
26
26
#include <sys/stat.h>
27
27
#include <mysys/mysys_err.h>
28
28
#include <drizzled/error.h>
29
 
#include <drizzled/query_id.h>
30
29
#include <drizzled/data_home.h>
31
30
#include <drizzled/sql_base.h>
32
31
#include <drizzled/lock.h>
40
39
#include <algorithm>
41
40
 
42
41
using namespace std;
 
42
using namespace drizzled;
43
43
 
44
44
extern "C"
45
45
{
57
57
const char * const Session::DEFAULT_WHERE= "field list";
58
58
extern pthread_key_t THR_Session;
59
59
extern pthread_key_t THR_Mem_root;
 
60
extern uint32_t max_used_connections;
 
61
extern drizzled::atomic<uint32_t> connection_count;
60
62
 
61
63
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
62
64
/* Used templates */
167
169
  session->row_count++;
168
170
}
169
171
 
170
 
Session::Session(Protocol *protocol_arg)
 
172
Session::Session(plugin::Protocol *protocol_arg)
171
173
  :
172
174
  Statement(&main_lex, &main_mem_root, /* statement id */ 0),
173
175
  Open_tables_state(refresh_version),
 
176
  scheduler(NULL),
 
177
  scheduler_arg(NULL),
174
178
  lock_id(&main_lock_id),
175
179
  user_time(0),
176
180
  arg_of_last_insert_id_function(false),
187
191
  derived_tables_processing(false),
188
192
  tablespace_op(false),
189
193
  m_lip(NULL),
190
 
  scheduler(0),
191
194
  cached_table(0)
192
195
{
193
 
  uint64_t tmp;
194
 
 
195
196
  memset(process_list_info, 0, PROCESS_LIST_WIDTH);
196
197
 
197
198
  /*
223
224
  replication_data= 0;
224
225
  mysys_var= 0;
225
226
  dbug_sentry=Session_SENTRY_MAGIC;
226
 
  client_capabilities= 0;                       // minimalistic client
227
227
  cleanup_done= abort_on_warning= no_warnings_for_error= false;
228
228
  peer_port= 0;                                 // For SHOW PROCESSLIST
229
229
  transaction.on= 1;
264
264
            (hash_get_key) get_var_key,
265
265
            (hash_free_key) free_user_var, 0);
266
266
 
267
 
  /* Protocol */
268
267
  protocol= protocol_arg;
269
268
  protocol->setSession(this);
270
269
 
271
 
  const Query_id& local_query_id= Query_id::get_query_id();
272
 
  tmp= sql_rnd();
273
 
  protocol->setRandom(tmp + (uint64_t) &protocol,
274
 
                      tmp + (uint64_t)local_query_id.value());
275
270
  substitute_null_with_insert_id = false;
276
271
  thr_lock_info_init(&lock_info); /* safety: will be reset after start */
277
272
  thr_lock_owner_init(&main_lock_id, &lock_info);
355
350
}
356
351
#endif
357
352
 
358
 
/*
359
 
  Init Session for query processing.
360
 
  This has to be called once before we call mysql_parse.
361
 
  See also comments in session.h.
362
 
*/
363
 
 
364
 
void Session::init_for_queries()
365
 
{
366
 
  set_time();
367
 
  ha_enable_transaction(this,true);
368
 
 
369
 
  reset_root_defaults(mem_root, variables.query_alloc_block_size,
370
 
                      variables.query_prealloc_size);
371
 
  reset_root_defaults(&transaction.mem_root,
372
 
                      variables.trans_alloc_block_size,
373
 
                      variables.trans_prealloc_size);
374
 
  transaction.xid_state.xid.null();
375
 
  transaction.xid_state.in_session=1;
376
 
}
377
 
 
378
 
 
379
353
/* Do operations that may take a long time */
380
354
 
381
355
void Session::cleanup(void)
498
472
{
499
473
  Session_CHECK_SENTRY(this);
500
474
  safe_mutex_assert_owner(&LOCK_delete);
501
 
  Scheduler &thread_scheduler= get_thread_scheduler();
502
475
 
503
476
  killed= state_to_set;
504
477
  if (state_to_set != Session::KILL_QUERY)
505
478
  {
506
 
    thread_scheduler.post_kill_notification(this);
 
479
    scheduler->killSession(this);
507
480
  }
508
481
  if (mysys_var)
509
482
  {
541
514
  Remember the location of thread info, the structure needed for
542
515
  sql_alloc() and the structure for the net buffer
543
516
*/
544
 
bool Session::store_globals()
 
517
bool Session::storeGlobals()
545
518
{
546
519
  /*
547
520
    Assert that thread_stack is initialized: it's necessary to be able
551
524
 
552
525
  if (pthread_setspecific(THR_Session,  this) ||
553
526
      pthread_setspecific(THR_Mem_root, &mem_root))
554
 
    return 1;
 
527
    return true;
 
528
 
555
529
  mysys_var=my_thread_var;
556
530
 
557
531
  /*
566
540
    created in another thread
567
541
  */
568
542
  thr_lock_info_init(&lock_info);
569
 
  return 0;
 
543
  return false;
570
544
}
571
545
 
 
546
/*
 
547
  Init Session for query processing.
 
548
  This has to be called once before we call mysql_parse.
 
549
  See also comments in session.h.
 
550
*/
 
551
 
572
552
void Session::prepareForQueries()
573
553
{
574
554
  if (variables.max_join_size == HA_POS_ERROR)
575
555
    options |= OPTION_BIG_SELECTS;
576
 
  if (client_capabilities & CLIENT_COMPRESS)
577
 
  {
578
 
    protocol->enableCompression();
579
 
  }
580
556
 
581
557
  version= refresh_version;
582
558
  set_proc_info(NULL);
583
559
  command= COM_SLEEP;
584
560
  set_time();
585
 
  init_for_queries();
 
561
  ha_enable_transaction(this,true);
 
562
 
 
563
  reset_root_defaults(mem_root, variables.query_alloc_block_size,
 
564
                      variables.query_prealloc_size);
 
565
  reset_root_defaults(&transaction.mem_root,
 
566
                      variables.trans_alloc_block_size,
 
567
                      variables.trans_prealloc_size);
 
568
  transaction.xid_state.xid.null();
 
569
  transaction.xid_state.in_session=1;
586
570
}
587
571
 
588
572
bool Session::initGlobals()
589
573
{
590
 
  if (store_globals())
 
574
  if (storeGlobals())
591
575
  {
592
576
    disconnect(ER_OUT_OF_RESOURCES, true);
593
577
    statistic_increment(aborted_connects, &LOCK_status);
594
 
    Scheduler &thread_scheduler= get_thread_scheduler();
595
 
    thread_scheduler.end_thread(this, 0);
596
 
    return false;
597
 
  }
598
 
  return true;
 
578
    return true;
 
579
  }
 
580
  return false;
 
581
}
 
582
 
 
583
void Session::run()
 
584
{
 
585
  if (initGlobals() || authenticate())
 
586
  {
 
587
    disconnect(0, true);
 
588
    return;
 
589
  }
 
590
 
 
591
  prepareForQueries();
 
592
 
 
593
  while (!protocol->haveError() && killed != KILL_CONNECTION)
 
594
  {
 
595
    if (!executeStatement())
 
596
      break;
 
597
  }
 
598
 
 
599
  disconnect(0, true);
 
600
}
 
601
 
 
602
bool Session::schedule()
 
603
{
 
604
  scheduler= get_thread_scheduler();
 
605
 
 
606
  ++connection_count;
 
607
 
 
608
  if (connection_count > max_used_connections)
 
609
    max_used_connections= connection_count;
 
610
 
 
611
  thread_id= variables.pseudo_thread_id= global_thread_id++;
 
612
 
 
613
  pthread_mutex_lock(&LOCK_thread_count);
 
614
  session_list.push_back(this);
 
615
  pthread_mutex_unlock(&LOCK_thread_count);
 
616
 
 
617
  if (scheduler->addSession(this))
 
618
  {
 
619
    char error_message_buff[DRIZZLE_ERRMSG_SIZE];
 
620
 
 
621
    killed= Session::KILL_CONNECTION;
 
622
 
 
623
    statistic_increment(aborted_connects, &LOCK_status);
 
624
 
 
625
    /* Can't use my_error() since store_globals has not been called. */
 
626
    /* TODO replace will better error message */
 
627
    snprintf(error_message_buff, sizeof(error_message_buff),
 
628
             ER(ER_CANT_CREATE_THREAD), 1);
 
629
    protocol->sendError(ER_CANT_CREATE_THREAD, error_message_buff);
 
630
    return true;
 
631
  }
 
632
 
 
633
  return false;
599
634
}
600
635
 
601
636
bool Session::authenticate()
602
637
{
603
638
  lex_start(this);
604
639
  if (protocol->authenticate())
605
 
    return true;
 
640
    return false;
606
641
 
607
642
  statistic_increment(aborted_connects, &LOCK_status);
608
 
  return false;
 
643
  return true;
609
644
}
610
645
 
611
646
bool Session::checkUser(const char *passwd, uint32_t passwd_len, const char *in_db)
727
762
    my_error(ER_XAER_RMFAIL, MYF(0), xa_state_names[transaction.xid_state.xa_state]);
728
763
    return false;
729
764
  }
730
 
  switch (completion) 
 
765
  switch (completion)
731
766
  {
732
767
    case COMMIT:
733
768
      /*
969
1004
  }
970
1005
  item->maybe_null= 1;
971
1006
  field_list.push_back(new Item_empty_string("Extra", 255, cs));
972
 
  return (result->send_fields(field_list,
973
 
                              Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF));
 
1007
  return (result->send_fields(field_list));
974
1008
}
975
1009
 
976
1010
/************************************************************************