~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/session.h

[patch 106/129] Merge patch for revision 1915 from InnoDB SVN:
revno: 1915
revision-id: svn-v4:16c675df-0fcb-4bc9-8058-dcc011a37293:branches/zip:6130
parent: svn-v4:16c675df-0fcb-4bc9-8058-dcc011a37293:branches/zip:6126
committer: marko
timestamp: Mon 2009-11-02 09:42:56 +0000
message:
  branches/zip: Free all resources at shutdown. Set pointers to NULL, so
  that Valgrind will not complain about freed data structures that are
  reachable via pointers.  This addresses Bug #45992 and Bug #46656.
  
  This patch is mostly based on changes copied from branches/embedded-1.0,
  mainly c5432, c3439, c3134, c2994, c2978, but also some other code was
  copied.  Some added cleanup code is specific to MySQL/InnoDB.
  
  rb://199 approved by Sunny Bains
modified:
  ChangeLog                      2425@16c675df-0fcb-4bc9-8058-dcc011a37293:branches%2Fzip%2FChangeLog
  btr/btr0sea.c                  2@16c675df-0fcb-4bc9-8058-dcc011a37293:trunk%2Fbtr%2Fbtr0sea.c
  buf/buf0buf.c                  2@16c675df-0fcb-4bc9-8058-dcc011a37293:trunk%2Fbuf%2Fbuf0buf.c
  dict/dict0dict.c               2@16c675df-0fcb-4bc9-8058-dcc011a37293:trunk%2Fdict%2Fdict0dict.c
  fil/fil0fil.c                  2@16c675df-0fcb-4bc9-8058-dcc011a37293:trunk%2Ffil%2Ffil0fil.c
  ibuf/ibuf0ibuf.c               2@16c675df-0fcb-4bc9-8058-dcc011a37293:trunk%2Fibuf%2Fibuf0ibuf.c
  include/btr0sea.h              2@16c675df-0fcb-4bc9-8058-dcc011a37293:trunk%2Finclude%2Fbtr0sea.h
  include/dict0dict.h            2@16c675df-0fcb-4bc9-8058-dcc011a37293:trunk%2Finclude%2Fdict0dict.h
  include/fil0fil.h              2@16c675df-0fcb-4bc9-8058-dcc011a37293:trunk%2Finclude%2Ffil0fil.h
  include/ibuf0ibuf.h            2@16c675df-0fcb-4bc9-8058-dcc011a37293:trunk%2Finclude%2Fibuf0ibuf.h
  include/lock0lock.h            2@16c675df-0fcb-4bc9-8058-dcc011a37293:trunk%2Finclude%2Flock0lock.h
  include/log0log.h              2@16c675df-0fcb-4bc9-8058-dcc011a37293:trunk%2Finclude%2Flog0log.h
  include/log0recv.h             2@16c675df-0fcb-4bc9-8058-dcc011a37293:trunk%2Finclude%2Flog0recv.h
  include/mem0mem.h              2@16c675df-0fcb-4bc9-8058-dcc011a37293:trunk%2Finclude%2Fmem0mem.h
  include/mem0pool.h             2@16c675df-0fcb-4bc9-8058-dcc011a37293:trunk%2Finclude%2Fmem0pool.h
  include/os0file.h              2@16c675df-0fcb-4bc9-8058-dcc011a37293:trunk%2Finclude%2Fos0file.h
  include/pars0pars.h            2@16c675df-0fcb-4bc9-8058-dcc011a37293:trunk%2Finclude%2Fpars0pars.h
  include/srv0srv.h              2@16c675df-0fcb-4bc9-8058-dcc011a37293:trunk%2Finclude%2Fsrv0srv.h
  include/thr0loc.h              2@16c675df-0fcb-4bc9-8058-dcc011a37293:trunk%2Finclude%2Fthr0loc.h
  include/trx0i_s.h              1864@16c675df-0fcb-4bc9-8058-dcc011a37293:branches%2Fzip%2Finclude%2Ftrx0i_s.h
  include/trx0purge.h            2@16c675df-0fcb-4bc9-8058-dcc011a37293:trunk%2Finclude%2Ftrx0purge.h
  include/trx0rseg.h             2@16c675df-0fcb-4bc9-8058-dcc011a37293:trunk%2Finclude%2Ftrx0rseg.h
  include/trx0sys.h              2@16c675df-0fcb-4bc9-8058-dcc011a37293:trunk%2Finclude%2Ftrx0sys.h
  include/trx0undo.h             2@16c675df-0fcb-4bc9-8058-dcc011a37293:trunk%2Finclude%2Ftrx0undo.h
  include/usr0sess.h             2@16c675df-0fcb-4bc9-8058-dcc011a37293:trunk%2Finclude%2Fusr0sess.h
  lock/lock0lock.c               2@16c675df-0fcb-4bc9-8058-dcc011a37293:trunk%2Flock%2Flock0lock.c
  log/log0log.c                  2@16c675df-0fcb-4bc9-8058-dcc011a37293:trunk%2Flog%2Flog0log.c
  log/log0recv.c                 2@16c675df-0fcb-4bc9-8058-dcc011a37293:trunk%2Flog%2Flog0recv.c
  mem/mem0dbg.c                  2@16c675df-0fcb-4bc9-8058-dcc011a37293:trunk%2Fmem%2Fmem0dbg.c
  mem/mem0pool.c                 2@16c675df-0fcb-4bc9-8058-dcc011a37293:trunk%2Fmem%2Fmem0pool.c
  os/os0file.c                   2@16c675df-0fcb-4bc9-8058-dcc011a37293:trunk%2Fos%2Fos0file.c
  os/os0sync.c                   2@16c675df-0fcb-4bc9-8058-dcc011a37293:trunk%2Fos%2Fos0sync.c
  os/os0thread.c                 2@16c675df-0fcb-4bc9-8058-dcc011a37293:trunk%2Fos%2Fos0thread.c
  pars/lexyy.c                   2@16c675df-0fcb-4bc9-8058-dcc011a37293:trunk%2Fpars%2Flexyy.c
  pars/pars0lex.l                2@16c675df-0fcb-4bc9-8058-dcc011a37293:trunk%2Fpars%2Fpars0lex.l
  que/que0que.c                  2@16c675df-0fcb-4bc9-8058-dcc011a37293:trunk%2Fque%2Fque0que.c
  srv/srv0srv.c                  2@16c675df-0fcb-4bc9-8058-dcc011a37293:trunk%2Fsrv%2Fsrv0srv.c
  srv/srv0start.c                2@16c675df-0fcb-4bc9-8058-dcc011a37293:trunk%2Fsrv%2Fsrv0start.c
  sync/sync0arr.c                2@16c675df-0fcb-4bc9-8058-dcc011a37293:trunk%2Fsync%2Fsync0arr.c
  sync/sync0sync.c               2@16c675df-0fcb-4bc9-8058-dcc011a37293:trunk%2Fsync%2Fsync0sync.c
  thr/thr0loc.c                  2@16c675df-0fcb-4bc9-8058-dcc011a37293:trunk%2Fthr%2Fthr0loc.c
  trx/trx0i_s.c                  1864@16c675df-0fcb-4bc9-8058-dcc011a37293:branches%2Fzip%2Ftrx%2Ftrx0i_s.c
  trx/trx0purge.c                2@16c675df-0fcb-4bc9-8058-dcc011a37293:trunk%2Ftrx%2Ftrx0purge.c
  trx/trx0rseg.c                 2@16c675df-0fcb-4bc9-8058-dcc011a37293:trunk%2Ftrx%2Ftrx0rseg.c
  trx/trx0sys.c                  2@16c675df-0fcb-4bc9-8058-dcc011a37293:trunk%2Ftrx%2Ftrx0sys.c
  trx/trx0undo.c                 2@16c675df-0fcb-4bc9-8058-dcc011a37293:trunk%2Ftrx%2Ftrx0undo.c
  usr/usr0sess.c                 2@16c675df-0fcb-4bc9-8058-dcc011a37293:trunk%2Fusr%2Fusr0sess.c
  ut/ut0mem.c                    2@16c675df-0fcb-4bc9-8058-dcc011a37293:trunk%2Fut%2Fut0mem.c
diff:
=== modified file 'ChangeLog'

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
#ifndef DRIZZLED_SESSION_H
22
22
#define DRIZZLED_SESSION_H
23
23
 
 
24
/* Classes in mysql */
 
25
 
24
26
#include "drizzled/plugin.h"
25
 
#include "drizzled/sql_locale.h"
 
27
#include <drizzled/sql_locale.h>
26
28
#include "drizzled/resource_context.h"
27
 
#include "drizzled/cursor.h"
28
 
#include "drizzled/current_session.h"
29
 
#include "drizzled/sql_error.h"
30
 
#include "drizzled/file_exchange.h"
31
 
#include "drizzled/select_result_interceptor.h"
32
 
#include "drizzled/statistics_variables.h"
33
 
#include "drizzled/xid.h"
 
29
#include <drizzled/cursor.h>
 
30
#include <drizzled/current_session.h>
 
31
#include <drizzled/sql_error.h>
 
32
#include <drizzled/file_exchange.h>
 
33
#include <drizzled/select_result_interceptor.h>
 
34
#include <drizzled/statistics_variables.h>
 
35
#include <drizzled/xid.h>
34
36
#include "drizzled/query_id.h"
35
37
#include "drizzled/named_savepoint.h"
36
38
#include "drizzled/transaction_context.h"
37
39
#include "drizzled/util/storable.h"
 
40
 
38
41
#include "drizzled/my_hash.h"
39
 
#include "drizzled/pthread_globals.h"
 
42
 
40
43
#include <netdb.h>
41
 
#include <sys/time.h>
42
 
#include <sys/resource.h>
43
 
 
44
 
#include <algorithm>
 
44
#include <map>
 
45
#include <string>
45
46
#include <bitset>
46
47
#include <deque>
47
 
#include <map>
48
 
#include <string>
49
 
 
50
 
#include "drizzled/security_context.h"
51
 
#include "drizzled/open_tables_state.h"
52
 
#include "drizzled/internal_error_handler.h"
53
 
#include "drizzled/diagnostics_area.h"
54
 
#include "drizzled/plugin/authorization.h"
 
48
 
 
49
#include "drizzled/internal/getrusage.h"
 
50
 
 
51
#include <drizzled/security_context.h>
 
52
#include <drizzled/open_tables_state.h>
 
53
 
 
54
#include <drizzled/internal_error_handler.h>
 
55
#include <drizzled/diagnostics_area.h>
 
56
 
 
57
#include <drizzled/plugin/authorization.h>
55
58
 
56
59
#include <boost/unordered_map.hpp>
57
 
 
58
 
#include <boost/thread/thread.hpp>
59
60
#include <boost/thread/mutex.hpp>
60
 
#include <boost/thread/shared_mutex.hpp>
61
61
#include <boost/thread/condition_variable.hpp>
62
 
#include <boost/make_shared.hpp>
63
 
 
64
62
 
65
63
#define MIN_HANDSHAKE_SIZE      6
66
64
 
80
78
class Statement;
81
79
class Resultset;
82
80
}
83
 
 
84
81
namespace internal
85
82
{
86
83
struct st_my_thread_var;
87
84
}
88
85
 
89
 
namespace table
90
 
{
91
 
class Placeholder;
92
 
}
93
 
 
94
86
class Lex_input_stream;
95
87
class user_var_entry;
96
88
class CopyField;
126
118
      of the INSERT ... ON DUPLICATE KEY UPDATE no matter whether the row
127
119
      was actually changed or not.
128
120
*/
129
 
class CopyInfo 
 
121
struct CopyInfo 
130
122
{
131
 
public:
132
123
  ha_rows records; /**< Number of processed records */
133
124
  ha_rows deleted; /**< Number of deleted records */
134
125
  ha_rows updated; /**< Number of updated records */
159
150
 
160
151
};
161
152
 
 
153
struct DrizzleLock
 
154
{
 
155
  Table **table;
 
156
  uint32_t table_count;
 
157
  uint32_t lock_count;
 
158
  THR_LOCK_DATA **locks;
 
159
 
 
160
  DrizzleLock() :
 
161
    table(0),
 
162
    table_count(0),
 
163
    lock_count(0),
 
164
    locks(0)
 
165
  { }
 
166
 
 
167
};
 
168
 
162
169
} /* namespace drizzled */
163
170
 
164
171
/** @TODO why is this in the middle of the file */
173
180
#define Session_SENTRY_MAGIC 0xfeedd1ff
174
181
#define Session_SENTRY_GONE  0xdeadbeef
175
182
 
176
 
struct drizzle_system_variables
 
183
struct system_variables
177
184
{
178
 
  drizzle_system_variables()
179
 
  {}
 
185
  system_variables() {};
180
186
  /*
181
187
    How dynamically allocated system variables are handled:
182
188
 
213
219
  uint64_t preload_buff_size;
214
220
  uint32_t read_buff_size;
215
221
  uint32_t read_rnd_buff_size;
216
 
  bool replicate_query;
217
222
  size_t sortbuff_size;
218
223
  uint32_t thread_handling;
219
224
  uint32_t tx_isolation;
247
252
  Time_zone *time_zone;
248
253
};
249
254
 
250
 
extern struct drizzle_system_variables global_system_variables;
 
255
extern struct system_variables global_system_variables;
251
256
 
252
257
} /* namespace drizzled */
253
258
 
310
315
 * all member variables that are not critical to non-internal operations of the
311
316
 * session object.
312
317
 */
313
 
typedef int64_t session_id_t;
314
 
 
315
318
class Session : public Open_tables_state
316
319
{
317
320
public:
318
321
  // Plugin storage in Session.
319
322
  typedef boost::unordered_map<std::string, util::Storable *, util::insensitive_hash, util::insensitive_equal_to> PropertyMap;
320
 
  typedef Session* Ptr;
321
 
  typedef boost::shared_ptr<Session> shared_ptr;
322
323
 
323
324
  /*
324
325
    MARK_COLUMNS_NONE:  Means mark_used_colums is not set and no indicator to
376
377
  {
377
378
    return mem_root;
378
379
  }
379
 
 
380
 
  uint64_t xa_id;
381
 
 
382
 
  uint64_t getXaId()
383
 
  {
384
 
    return xa_id;
385
 
  }
386
 
 
387
 
  void setXaId(uint64_t in_xa_id)
388
 
  {
389
 
    xa_id= in_xa_id; 
390
 
  }
391
 
 
392
380
  /**
393
381
   * Uniquely identifies each statement object in thread scope; change during
394
382
   * statement lifetime.
403
391
    return lex;
404
392
  }
405
393
  /** query associated with this statement */
406
 
  typedef boost::shared_ptr<const std::string> QueryString;
407
 
private:
408
 
  boost::shared_ptr<std::string> query;
409
 
 
410
 
  // Never allow for a modification of this outside of the class. c_str()
411
 
  // requires under some setup non const, you must copy the QueryString in
412
 
  // order to use it.
413
 
public:
414
 
  QueryString getQueryString() const
415
 
  {
416
 
    return query;
417
 
  }
418
 
 
419
 
  void resetQueryString()
420
 
  {
421
 
    query.reset();
422
 
    _state.reset();
423
 
  }
424
 
 
425
 
  /*
426
 
    We need to copy the lock on the string in order to make sure we have a stable string.
427
 
    Once this is done we can use it to build a const char* which can be handed off for
428
 
    a method to use (Innodb is currently the only engine using this).
429
 
  */
430
 
  const char *getQueryStringCopy(size_t &length)
431
 
  {
432
 
    QueryString tmp_string(getQueryString());
433
 
 
434
 
    assert(tmp_string);
435
 
    if (not tmp_string)
436
 
    {
437
 
      length= 0;
438
 
      return 0;
439
 
    }
440
 
 
441
 
    length= tmp_string->length();
442
 
    char *to_return= strmake(tmp_string->c_str(), tmp_string->length());
443
 
    return to_return;
444
 
  }
445
 
 
446
 
  class State {
447
 
    std::vector <char> _query;
448
 
 
449
 
  public:
450
 
    typedef boost::shared_ptr<State> const_shared_ptr;
451
 
 
452
 
    State(const char *in_packet, size_t in_packet_length)
453
 
    {
454
 
      if (in_packet_length)
455
 
      {
456
 
        size_t minimum= std::min(in_packet_length, static_cast<size_t>(PROCESS_LIST_WIDTH));
457
 
        _query.resize(minimum + 1);
458
 
        memcpy(&_query[0], in_packet, minimum);
459
 
      }
460
 
      else
461
 
      {
462
 
        _query.resize(0);
463
 
      }
464
 
    }
465
 
 
466
 
    const char *query() const
467
 
    {
468
 
      if (_query.size())
469
 
        return &_query[0];
470
 
 
471
 
      return "";
472
 
    }
473
 
 
474
 
    const char *query(size_t &size) const
475
 
    {
476
 
      if (_query.size())
477
 
      {
478
 
        size= _query.size() -1;
479
 
        return &_query[0];
480
 
      }
481
 
 
482
 
      size= 0;
483
 
      return "";
484
 
    }
485
 
  protected:
486
 
    friend class Session;
487
 
    typedef boost::shared_ptr<State> shared_ptr;
488
 
  };
489
 
private:
490
 
  State::shared_ptr  _state; 
491
 
public:
492
 
 
493
 
  State::const_shared_ptr state()
494
 
  {
495
 
    return _state;
496
 
  }
 
394
  std::string query;
497
395
 
498
396
  /**
499
397
    Name of the current (default) database.
507
405
    the Session of that thread); that thread is (and must remain, for now) the
508
406
    only responsible for freeing this member.
509
407
  */
510
 
private:
511
 
  util::string::shared_ptr _schema;
512
 
public:
513
 
 
514
 
  util::string::const_shared_ptr schema() const
515
 
  {
516
 
    if (_schema)
517
 
      return _schema;
518
 
 
519
 
    return util::string::const_shared_ptr(new std::string(""));
520
 
  }
521
 
  std::string catalog;
 
408
  std::string db;
522
409
  /* current cache key */
523
410
  std::string query_cache_key;
524
411
  /**
531
418
 
532
419
  memory::Root warn_root; /**< Allocation area for warnings and errors */
533
420
  plugin::Client *client; /**< Pointer to client object */
534
 
 
535
 
  void setClient(plugin::Client *client_arg);
536
 
 
537
 
  plugin::Client *getClient()
538
 
  {
539
 
    return client;
540
 
  }
541
 
 
542
421
  plugin::Scheduler *scheduler; /**< Pointer to scheduler object */
543
422
  void *scheduler_arg; /**< Pointer to the optional scheduler argument */
544
 
 
 
423
private:
545
424
  typedef boost::unordered_map< std::string, user_var_entry *, util::insensitive_hash, util::insensitive_equal_to> UserVars;
546
 
private:
547
425
  typedef std::pair< UserVars::iterator, UserVars::iterator > UserVarsRange;
548
426
  UserVars user_vars; /**< Hash of user variables defined during the session's lifetime */
549
427
 
550
428
public:
551
 
 
552
 
  const UserVars &getUserVariables() const
553
 
  {
554
 
    return user_vars;
555
 
  }
556
 
 
557
 
  drizzle_system_variables variables; /**< Mutable local variables local to the session */
 
429
  struct system_variables variables; /**< Mutable local variables local to the session */
558
430
  struct system_status_var status_var; /**< Session-local status counters */
559
431
  THR_LOCK_INFO lock_info; /**< Locking information for this session */
560
432
  THR_LOCK_OWNER main_lock_id; /**< To use for conventional queries */
561
433
  THR_LOCK_OWNER *lock_id; /**< If not main_lock_id, points to the lock_id of a cursor. */
 
434
private:
 
435
  boost::mutex LOCK_delete; /**< Locked before session is deleted */
 
436
public:
 
437
 
 
438
  void lockForDelete()
 
439
  {
 
440
    LOCK_delete.lock();
 
441
  }
 
442
 
 
443
  void unlockForDelete()
 
444
  {
 
445
    LOCK_delete.unlock();
 
446
  }
 
447
 
 
448
  /**
 
449
   * A peek into the query string for the session. This is a best effort
 
450
   * delivery, there is no guarantee whether the content is meaningful.
 
451
   */
 
452
  char process_list_info[PROCESS_LIST_WIDTH+1];
562
453
 
563
454
  /**
564
455
   * A pointer to the stack frame of the scheduler thread
599
490
  /**
600
491
   * Is this session viewable by the current user?
601
492
   */
602
 
  bool isViewable() const;
 
493
  bool isViewable() const
 
494
  {
 
495
    return plugin::Authorization::isAuthorized(current_session->getSecurityContext(),
 
496
                                               this,
 
497
                                               false);
 
498
  }
603
499
 
604
500
  /**
605
501
    Used in error messages to tell user in what part of MySQL we found an
615
511
  */
616
512
  uint32_t dbug_sentry; /**< watch for memory corruption */
617
513
private:
618
 
  boost::thread::id boost_thread_id;
619
 
  boost_thread_shared_ptr _thread;
620
 
  boost::this_thread::disable_interruption *interrupt;
621
 
 
622
514
  internal::st_my_thread_var *mysys_var;
623
515
public:
624
516
 
625
 
  boost_thread_shared_ptr &getThread()
626
 
  {
627
 
    return _thread;
628
 
  }
629
 
 
630
 
  void pushInterrupt(boost::this_thread::disable_interruption *interrupt_arg)
631
 
  {
632
 
    interrupt= interrupt_arg;
633
 
  }
634
 
 
635
 
  boost::this_thread::disable_interruption &getThreadInterupt()
636
 
  {
637
 
    assert(interrupt);
638
 
    return *interrupt;
639
 
  }
640
 
 
641
517
  internal::st_my_thread_var *getThreadVar()
642
518
  {
643
519
    return mysys_var;
644
520
  }
645
521
 
 
522
  void resetThreadVar()
 
523
  {
 
524
    mysys_var= NULL;
 
525
  }
646
526
  /**
647
527
   * Type of current query: COM_STMT_PREPARE, COM_QUERY, etc. Set from
648
528
   * first byte of the packet in executeStatement()
681
561
  ResourceContext *getResourceContext(const plugin::MonitoredInTransaction *monitored,
682
562
                                      size_t index= 0);
683
563
 
684
 
  /**
685
 
   * Structure used to manage "statement transactions" and
686
 
   * "normal transactions". In autocommit mode, the normal transaction is
687
 
   * equivalent to the statement transaction.
688
 
   *
689
 
   * Storage engines will be registered here when they participate in
690
 
   * a transaction. No engine is registered more than once.
691
 
   */
692
564
  struct st_transactions {
693
565
    std::deque<NamedSavepoint> savepoints;
694
 
 
695
 
    /**
696
 
     * The normal transaction (since BEGIN WORK).
697
 
     *
698
 
     * Contains a list of all engines that have participated in any of the
699
 
     * statement transactions started within the context of the normal
700
 
     * transaction.
701
 
     *
702
 
     * @note In autocommit mode, this is empty.
703
 
     */
704
 
    TransactionContext all;
705
 
 
706
 
    /**
707
 
     * The statment transaction.
708
 
     *
709
 
     * Contains a list of all engines participating in the given statement.
710
 
     *
711
 
     * @note In autocommit mode, this will be used to commit/rollback the
712
 
     * normal transaction.
713
 
     */
714
 
    TransactionContext stmt;
715
 
 
 
566
    TransactionContext all; ///< Trans since BEGIN WORK
 
567
    TransactionContext stmt; ///< Trans for current statement
716
568
    XID_STATE xid_state;
717
569
 
718
570
    void cleanup()
730
582
  Field *dup_field;
731
583
  sigset_t signals;
732
584
 
733
 
  // As of right now we do not allow a concurrent execute to launch itself
734
 
private:
735
 
  bool concurrent_execute_allowed;
736
 
public:
737
 
 
738
 
  void setConcurrentExecute(bool arg)
739
 
  {
740
 
    concurrent_execute_allowed= arg;
741
 
  }
742
 
 
743
 
  bool isConcurrentExecuteAllowed() const
744
 
  {
745
 
    return concurrent_execute_allowed;
746
 
  }
747
 
 
748
585
  /* Tells if LAST_INSERT_ID(#) was called for the current statement */
749
586
  bool arg_of_last_insert_id_function;
750
 
 
751
587
  /*
752
588
    ALL OVER THIS FILE, "insert_id" means "*automatically generated* value for
753
589
    insertion into an auto_increment column".
849
685
    create_sort_index(); may differ from examined_row_count.
850
686
  */
851
687
  uint32_t row_count;
852
 
  session_id_t thread_id;
 
688
  uint64_t thread_id;
853
689
  uint32_t tmp_table;
854
 
  enum global_read_lock_t
855
 
  {
856
 
    NONE= 0,
857
 
    GOT_GLOBAL_READ_LOCK= 1,
858
 
    MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT= 2
859
 
  };
860
 
private:
861
 
  global_read_lock_t _global_read_lock;
862
 
 
863
 
public:
864
 
 
865
 
  global_read_lock_t isGlobalReadLock() const
866
 
  {
867
 
    return _global_read_lock;
868
 
  }
869
 
 
870
 
  void setGlobalReadLock(global_read_lock_t arg)
871
 
  {
872
 
    _global_read_lock= arg;
873
 
  }
874
 
 
875
 
  DrizzleLock *lockTables(Table **tables, uint32_t count, uint32_t flags, bool *need_reopen);
876
 
  bool lockGlobalReadLock();
877
 
  bool lock_table_names(TableList *table_list);
878
 
  bool lock_table_names_exclusively(TableList *table_list);
879
 
  bool makeGlobalReadLockBlockCommit();
880
 
  bool abortLockForThread(Table *table);
881
 
  bool wait_if_global_read_lock(bool abort_on_refresh, bool is_not_commit);
882
 
  int lock_table_name(TableList *table_list);
883
 
  void abortLock(Table *table);
884
 
  void removeLock(Table *table);
885
 
  void unlockReadTables(DrizzleLock *sql_lock);
886
 
  void unlockSomeTables(Table **table, uint32_t count);
887
 
  void unlockTables(DrizzleLock *sql_lock);
888
 
  void startWaitingGlobalReadLock();
889
 
  void unlockGlobalReadLock();
890
 
 
891
 
private:
892
 
  int unlock_external(Table **table, uint32_t count);
893
 
  int lock_external(Table **tables, uint32_t count);
894
 
  bool wait_for_locked_table_names(TableList *table_list);
895
 
  DrizzleLock *get_lock_data(Table **table_ptr, uint32_t count,
896
 
                             bool should_lock, Table **write_lock_used);
897
 
public:
898
 
 
 
690
  uint32_t global_read_lock;
899
691
  uint32_t server_status;
900
692
  uint32_t open_options;
901
693
  uint32_t select_number; /**< number of select (used for EXPLAIN) */
903
695
  enum_tx_isolation session_tx_isolation;
904
696
  enum_check_fields count_cuted_fields;
905
697
 
906
 
  enum killed_state_t
 
698
  enum killed_state
907
699
  {
908
700
    NOT_KILLED,
909
701
    KILL_BAD_DATA,
911
703
    KILL_QUERY,
912
704
    KILLED_NO_VALUE /* means none of the above states apply */
913
705
  };
914
 
private:
915
 
  killed_state_t volatile _killed;
916
 
 
917
 
public:
918
 
 
919
 
  void setKilled(killed_state_t arg)
920
 
  {
921
 
    _killed= arg;
922
 
  }
923
 
 
924
 
  killed_state_t getKilled()
925
 
  {
926
 
    return _killed;
927
 
  }
928
 
 
929
 
  volatile killed_state_t *getKilledPtr() // Do not use this method, it is here for historical convience.
930
 
  {
931
 
    return &_killed;
932
 
  }
933
 
 
934
 
  bool is_admin_connection;
 
706
  killed_state volatile killed;
 
707
 
935
708
  bool some_tables_deleted;
936
709
  bool no_errors;
937
710
  bool password;
1020
793
  }
1021
794
 
1022
795
  /** Returns the current query ID */
1023
 
  query_id_t getQueryId()  const
 
796
  inline query_id_t getQueryId()  const
1024
797
  {
1025
798
    return query_id;
1026
799
  }
1038
811
    return warn_query_id;
1039
812
  }
1040
813
 
 
814
  /** Returns the current query text */
 
815
  inline const std::string &getQueryString()  const
 
816
  {
 
817
    return query;
 
818
  }
 
819
 
 
820
  /** Returns the length of the current query text */
 
821
  inline size_t getQueryLength() const
 
822
  {
 
823
    if (! query.empty())
 
824
      return query.length();
 
825
    else
 
826
      return 0;
 
827
  }
 
828
 
1041
829
  /** Accessor method returning the session's ID. */
1042
 
  inline session_id_t getSessionId()  const
 
830
  inline uint64_t getSessionId()  const
1043
831
  {
1044
832
    return thread_id;
1045
833
  }
1130
918
   */
1131
919
  void cleanup_after_query();
1132
920
  bool storeGlobals();
1133
 
  void awake(Session::killed_state_t state_to_set);
 
921
  void awake(Session::killed_state state_to_set);
1134
922
  /**
1135
923
   * Pulls thread-specific variables into Session state.
1136
924
   *
1213
1001
  /**
1214
1002
   * Schedule a session to be run on the default scheduler.
1215
1003
   */
1216
 
  static bool schedule(Session::shared_ptr&);
1217
 
 
1218
 
  static void unlink(Session::shared_ptr&);
 
1004
  bool schedule();
1219
1005
 
1220
1006
  /*
1221
1007
    For enter_cond() / exit_cond() to work the mutex must be got before
1222
1008
    enter_cond(); this mutex is then released by exit_cond().
1223
1009
    Usage must be: lock mutex; enter_cond(); your code; exit_cond().
1224
1010
  */
1225
 
  const char* enter_cond(boost::condition_variable_any &cond, boost::mutex &mutex, const char* msg);
 
1011
  const char* enter_cond(boost::condition_variable &cond, boost::mutex &mutex, const char* msg);
1226
1012
  void exit_cond(const char* old_msg);
1227
1013
 
1228
1014
  inline time_t query_start() { return start_time; }
1229
1015
  inline void set_time()
1230
1016
  {
1231
 
    boost::posix_time::ptime mytime(boost::posix_time::microsec_clock::local_time());
1232
 
    boost::posix_time::ptime epoch(boost::gregorian::date(1970,1,1));
1233
 
    start_utime= utime_after_lock= (mytime-epoch).total_microseconds();
1234
 
 
1235
1017
    if (user_time)
1236
1018
    {
1237
1019
      start_time= user_time;
1238
 
      connect_microseconds= start_utime;
 
1020
      connect_microseconds= start_utime= utime_after_lock= my_micro_time();
1239
1021
    }
1240
 
    else 
1241
 
      start_time= (mytime-epoch).total_seconds();
 
1022
    else
 
1023
      start_utime= utime_after_lock= my_micro_time_and_time(&start_time);
1242
1024
  }
1243
1025
  inline void   set_current_time()    { start_time= time(NULL); }
1244
1026
  inline void   set_time(time_t t)
1245
1027
  {
1246
1028
    start_time= user_time= t;
1247
 
    boost::posix_time::ptime mytime(boost::posix_time::microsec_clock::local_time());
1248
 
    boost::posix_time::ptime epoch(boost::gregorian::date(1970,1,1));
1249
 
    uint64_t t_mark= (mytime-epoch).total_microseconds();
1250
 
 
1251
 
    start_utime= utime_after_lock= t_mark;
1252
 
  }
1253
 
  void set_time_after_lock()  { 
1254
 
     boost::posix_time::ptime mytime(boost::posix_time::microsec_clock::local_time());
1255
 
     boost::posix_time::ptime epoch(boost::gregorian::date(1970,1,1));
1256
 
     utime_after_lock= (mytime-epoch).total_microseconds();
1257
 
  }
 
1029
    start_utime= utime_after_lock= my_micro_time();
 
1030
  }
 
1031
  void set_time_after_lock()  { utime_after_lock= my_micro_time(); }
1258
1032
  /**
1259
1033
   * Returns the current micro-timestamp
1260
1034
   */
1261
1035
  inline uint64_t getCurrentTimestamp()  
1262
1036
  { 
1263
 
    boost::posix_time::ptime mytime(boost::posix_time::microsec_clock::local_time());
1264
 
    boost::posix_time::ptime epoch(boost::gregorian::date(1970,1,1));
1265
 
    uint64_t t_mark= (mytime-epoch).total_microseconds();
1266
 
 
1267
 
    return t_mark; 
 
1037
    return my_micro_time(); 
1268
1038
  }
1269
1039
  inline uint64_t found_rows(void)
1270
1040
  {
1275
1045
  {
1276
1046
    return server_status & SERVER_STATUS_IN_TRANS;
1277
1047
  }
 
1048
  inline bool fill_derived_tables()
 
1049
  {
 
1050
    return !lex->only_view_structure();
 
1051
  }
 
1052
 
1278
1053
  LEX_STRING *make_lex_string(LEX_STRING *lex_str,
1279
1054
                              const char* str, uint32_t length,
1280
1055
                              bool allocate_lex_string);
1290
1065
    @todo: To silence an error, one should use Internal_error_handler
1291
1066
    mechanism. In future this function will be removed.
1292
1067
  */
1293
 
  inline void clear_error(bool full= false)
 
1068
  inline void clear_error()
1294
1069
  {
1295
1070
    if (main_da.is_error())
1296
1071
      main_da.reset_diagnostics_area();
1297
 
 
1298
 
    if (full)
1299
 
    {
1300
 
      drizzle_reset_errors(this, true);
1301
 
    }
1302
 
  }
1303
 
 
1304
 
  void clearDiagnostics()
1305
 
  {
1306
 
    main_da.reset_diagnostics_area();
 
1072
    return;
1307
1073
  }
1308
1074
 
1309
1075
  /**
1347
1113
  void end_statement();
1348
1114
  inline int killed_errno() const
1349
1115
  {
1350
 
    killed_state_t killed_val; /* to cache the volatile 'killed' */
1351
 
    return (killed_val= _killed) != KILL_BAD_DATA ? killed_val : 0;
 
1116
    killed_state killed_val; /* to cache the volatile 'killed' */
 
1117
    return (killed_val= killed) != KILL_BAD_DATA ? killed_val : 0;
1352
1118
  }
1353
1119
  void send_kill_message() const;
1354
1120
  /* return true if we will abort query if we make a warning now */
1377
1143
    database usually involves other actions, like switching other database
1378
1144
    attributes including security context. In the future, this operation
1379
1145
    will be made private and more convenient interface will be provided.
 
1146
 
 
1147
    @return Operation status
 
1148
      @retval false Success
 
1149
      @retval true  Out-of-memory error
1380
1150
  */
1381
 
  void set_db(const std::string &new_db);
 
1151
  bool set_db(const std::string &new_db);
1382
1152
 
1383
1153
  /*
1384
1154
    Copy the current database to the argument. Use the current arena to
1443
1213
   * Current implementation does not depend on that, but future changes
1444
1214
   * should be done with this in mind; 
1445
1215
   *
1446
 
   * @param passwd Scrambled password received from client
1447
 
   * @param db Database name to connect to, may be NULL
 
1216
   * @param  Scrambled password received from client
 
1217
   * @param  Length of scrambled password
 
1218
   * @param  Database name to connect to, may be NULL
1448
1219
   */
1449
 
  bool checkUser(const std::string &passwd, const std::string &db);
 
1220
  bool checkUser(const char *passwd, uint32_t passwd_len, const char *db);
1450
1221
  
1451
1222
  /**
1452
1223
   * Returns the timestamp (in microseconds) of when the Session 
1617
1388
   * set to query_id of original query.
1618
1389
   */
1619
1390
  void mark_used_tables_as_free_for_reuse(Table *table);
 
1391
  /**
 
1392
    Mark all temporary tables which were used by the current statement or
 
1393
    substatement as free for reuse, but only if the query_id can be cleared.
 
1394
 
 
1395
    @param session thread context
 
1396
 
 
1397
    @remark For temp tables associated with a open SQL HANDLER the query_id
 
1398
            is not reset until the HANDLER is closed.
 
1399
  */
 
1400
  void mark_temp_tables_as_free_for_reuse();
1620
1401
 
1621
1402
public:
1622
1403
 
1658
1439
  }
1659
1440
  void refresh_status();
1660
1441
  user_var_entry *getVariable(LEX_STRING &name, bool create_if_not_exists);
1661
 
  user_var_entry *getVariable(const std::string  &name, bool create_if_not_exists);
1662
 
  void setVariable(const std::string &name, const std::string &value);
1663
1442
  
1664
1443
  /**
1665
1444
   * Closes all tables used by the current substatement, or all tables
1669
1448
  void close_old_data_files(bool morph_locks= false,
1670
1449
                            bool send_refresh= false);
1671
1450
  void close_open_tables();
1672
 
  void close_data_files_and_morph_locks(const TableIdentifier &identifier);
 
1451
  void close_data_files_and_morph_locks(TableIdentifier &identifier);
1673
1452
 
1674
1453
private:
1675
1454
  bool free_cached_table();
1700
1479
   */
1701
1480
  bool openTablesLock(TableList *tables);
1702
1481
 
 
1482
  /**
 
1483
   * Open all tables in list and process derived tables
 
1484
   *
 
1485
   * @param Pointer to a list of tables for open
 
1486
   * @param Bitmap of flags to modify how the tables will be open:
 
1487
   *        DRIZZLE_LOCK_IGNORE_FLUSH - open table even if someone has
 
1488
   *        done a flush or namelock on it.
 
1489
   *
 
1490
   * @retval
 
1491
   *  false - ok
 
1492
   * @retval
 
1493
   *  true  - error
 
1494
   *
 
1495
   * @note
 
1496
   *
 
1497
   * This is to be used on prepare stage when you don't read any
 
1498
   * data from the tables.
 
1499
   */
 
1500
  bool openTables(TableList *tables, uint32_t flags= 0);
 
1501
 
1703
1502
  int open_tables_from_list(TableList **start, uint32_t *counter, uint32_t flags= 0);
1704
1503
 
1705
1504
  Table *openTableLock(TableList *table_list, thr_lock_type lock_type);
1706
1505
  Table *openTable(TableList *table_list, bool *refresh, uint32_t flags= 0);
1707
1506
 
1708
1507
  void unlink_open_table(Table *find);
1709
 
  void drop_open_table(Table *table, const TableIdentifier &identifier);
 
1508
  void drop_open_table(Table *table, TableIdentifier &identifier);
1710
1509
  void close_cached_table(Table *table);
1711
1510
 
1712
1511
  /* Create a lock in the cache */
1713
 
  table::Placeholder *table_cache_insert_placeholder(const TableIdentifier &identifier);
1714
 
  bool lock_table_name_if_not_cached(const TableIdentifier &identifier, Table **table);
 
1512
  Table *table_cache_insert_placeholder(const char *db_name, const char *table_name);
 
1513
  bool lock_table_name_if_not_cached(TableIdentifier &identifier, Table **table);
1715
1514
 
1716
1515
  typedef boost::unordered_map<std::string, message::Table, util::insensitive_hash, util::insensitive_equal_to> TableMessageCache;
1717
 
 
1718
 
  class TableMessages
1719
 
  {
1720
 
    TableMessageCache table_message_cache;
1721
 
 
1722
 
  public:
1723
 
    bool storeTableMessage(const TableIdentifier &identifier, message::Table &table_message);
1724
 
    bool removeTableMessage(const TableIdentifier &identifier);
1725
 
    bool getTableMessage(const TableIdentifier &identifier, message::Table &table_message);
1726
 
    bool doesTableMessageExist(const TableIdentifier &identifier);
1727
 
    bool renameTableMessage(const TableIdentifier &from, const TableIdentifier &to);
1728
 
 
1729
 
  };
 
1516
  TableMessageCache table_message_cache;
 
1517
 
 
1518
  bool storeTableMessage(const TableIdentifier &identifier, message::Table &table_message);
 
1519
  bool removeTableMessage(const TableIdentifier &identifier);
 
1520
  bool getTableMessage(const TableIdentifier &identifier, message::Table &table_message);
 
1521
  bool doesTableMessageExist(const TableIdentifier &identifier);
 
1522
  bool renameTableMessage(const TableIdentifier &from, const TableIdentifier &to);
 
1523
 
 
1524
  /* Work with temporary tables */
 
1525
  Table *find_temporary_table(TableList *table_list);
 
1526
  Table *find_temporary_table(const char *db, const char *table_name);
 
1527
  Table *find_temporary_table(TableIdentifier &identifier);
 
1528
 
 
1529
  void doGetTableNames(CachedDirectory &directory,
 
1530
                       const SchemaIdentifier &schema_identifier,
 
1531
                       std::set<std::string>& set_of_names);
 
1532
  void doGetTableNames(const SchemaIdentifier &schema_identifier,
 
1533
                       std::set<std::string>& set_of_names);
 
1534
 
 
1535
  void doGetTableIdentifiers(CachedDirectory &directory,
 
1536
                             const SchemaIdentifier &schema_identifier,
 
1537
                             TableIdentifiers &set_of_identifiers);
 
1538
  void doGetTableIdentifiers(const SchemaIdentifier &schema_identifier,
 
1539
                             TableIdentifiers &set_of_identifiers);
 
1540
 
 
1541
  int doGetTableDefinition(const drizzled::TableIdentifier &identifier,
 
1542
                           message::Table &table_proto);
 
1543
  bool doDoesTableExist(const drizzled::TableIdentifier &identifier);
 
1544
 
 
1545
  void close_temporary_tables();
 
1546
  void close_temporary_table(Table *table);
 
1547
  // The method below just handles the de-allocation of the table. In
 
1548
  // a better memory type world, this would not be needed.
1730
1549
private:
1731
 
  TableMessages _table_message_cache;
1732
 
 
 
1550
  void nukeTable(Table *table);
1733
1551
public:
1734
 
  TableMessages &getMessageCache()
1735
 
  {
1736
 
    return _table_message_cache;
1737
 
  }
 
1552
 
 
1553
  void dumpTemporaryTableNames(const char *id);
 
1554
  int drop_temporary_table(TableList *table_list);
 
1555
  bool rm_temporary_table(plugin::StorageEngine *base, TableIdentifier &identifier);
 
1556
  bool rm_temporary_table(TableIdentifier &identifier, bool best_effort= false);
 
1557
  Table *open_temporary_table(TableIdentifier &identifier,
 
1558
                              bool link_in_list= true);
1738
1559
 
1739
1560
  /* Reopen operations */
1740
1561
  bool reopen_tables(bool get_locks, bool mark_share_as_old);
 
1562
  bool reopen_name_locked_table(TableList* table_list, bool link_in);
1741
1563
  bool close_cached_tables(TableList *tables, bool wait_for_refresh, bool wait_for_placeholders);
1742
1564
 
1743
 
  void wait_for_condition(boost::mutex &mutex, boost::condition_variable_any &cond);
 
1565
  void wait_for_condition(boost::mutex &mutex, boost::condition_variable &cond);
1744
1566
  int setup_conds(TableList *leaves, COND **conds);
1745
1567
  int lock_tables(TableList *tables, uint32_t count, bool *need_reopen);
1746
1568
 
 
1569
  Table *create_virtual_tmp_table(List<CreateField> &field_list);
 
1570
  
1747
1571
  drizzled::util::Storable *getProperty(const std::string &arg)
1748
1572
  {
1749
1573
    return life_properties[arg];
1770
1594
    if (variables.storage_engine)
1771
1595
      return variables.storage_engine;
1772
1596
    return global_system_variables.storage_engine;
1773
 
  }
 
1597
  };
 
1598
 
 
1599
  static void unlink(Session *session);
1774
1600
 
1775
1601
  void get_xid(DRIZZLE_XID *xid); // Innodb only
1776
1602
 
1777
 
  table::Instance *getInstanceTable();
1778
 
  table::Instance *getInstanceTable(List<CreateField> &field_list);
 
1603
  TableShareInstance *getTemporaryShare(TableIdentifier::Type type_arg);
1779
1604
 
1780
1605
private:
1781
1606
  bool resetUsage()
1803
1628
  // This lives throughout the life of Session
1804
1629
  bool use_usage;
1805
1630
  PropertyMap life_properties;
1806
 
  std::vector<table::Instance *> temporary_shares;
 
1631
  std::vector<TableShareInstance *> temporary_shares;
1807
1632
  struct rusage usage;
1808
1633
};
1809
1634
 
1833
1658
 * A structure used to describe sort information
1834
1659
 * for a field or item used in ORDER BY.
1835
1660
 */
1836
 
class SortField 
 
1661
struct SortField 
1837
1662
{
1838
 
public:
1839
1663
  Field *field; /**< Field to sort */
1840
1664
  Item  *item; /**< Item if not sorting fields */
1841
1665
  size_t length; /**< Length of sort field */
1887
1711
static const std::bitset<CF_BIT_SIZE> CF_SHOW_TABLE_COMMAND(1 << CF_BIT_SHOW_TABLE_COMMAND);
1888
1712
static const std::bitset<CF_BIT_SIZE> CF_WRITE_LOGS_COMMAND(1 << CF_BIT_WRITE_LOGS_COMMAND);
1889
1713
 
1890
 
namespace display  {
1891
 
const std::string &type(drizzled::Session::global_read_lock_t type);
1892
 
size_t max_string_length(drizzled::Session::global_read_lock_t type);
1893
 
} /* namespace display */
1894
 
 
1895
1714
} /* namespace drizzled */
1896
1715
 
1897
1716
#endif /* DRIZZLED_SESSION_H */