~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/session.h

  • Committer: Brian Aker
  • Date: 2010-05-26 21:49:18 UTC
  • mto: This revision was merged to the branch mainline in revision 1568.
  • Revision ID: brian@gaz-20100526214918-8kdibq48e9lnyr6t
This fixes bug 586009, increases the size of the log files so that the UNION
test doesn't hit Innodb's default limit. Increases the size of the initial
Innodb data file, and fixes one case where an empty string on error was
causing a crash on OSX.

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
 
#include "drizzled/util/storable.h"
38
 
#include "drizzled/my_hash.h"
39
 
#include "drizzled/pthread_globals.h"
 
39
 
40
40
#include <netdb.h>
41
 
#include <sys/time.h>
42
 
#include <sys/resource.h>
43
 
 
44
 
#include <algorithm>
 
41
#include <map>
 
42
#include <string>
45
43
#include <bitset>
46
44
#include <deque>
47
 
#include <map>
48
 
#include <string>
49
 
 
50
 
#include "drizzled/identifier.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"
55
 
 
56
 
#include <boost/unordered_map.hpp>
57
 
 
58
 
#include <boost/thread/thread.hpp>
59
 
#include <boost/thread/mutex.hpp>
60
 
#include <boost/thread/shared_mutex.hpp>
61
 
#include <boost/thread/condition_variable.hpp>
62
 
#include <boost/make_shared.hpp>
63
 
 
 
45
 
 
46
#include <drizzled/security_context.h>
 
47
#include <drizzled/open_tables_state.h>
 
48
 
 
49
#include <drizzled/internal_error_handler.h>
 
50
#include <drizzled/diagnostics_area.h>
 
51
 
 
52
#include <drizzled/plugin/authorization.h>
64
53
 
65
54
#define MIN_HANDSHAKE_SIZE      6
66
55
 
78
67
{
79
68
class Transaction;
80
69
class Statement;
81
 
class Resultset;
82
70
}
83
 
 
84
71
namespace internal
85
72
{
86
73
struct st_my_thread_var;
87
74
}
88
75
 
89
 
namespace table
90
 
{
91
 
class Placeholder;
92
 
}
93
 
 
94
76
class Lex_input_stream;
95
77
class user_var_entry;
96
78
class CopyField;
126
108
      of the INSERT ... ON DUPLICATE KEY UPDATE no matter whether the row
127
109
      was actually changed or not.
128
110
*/
129
 
class CopyInfo 
 
111
typedef struct st_copy_info 
130
112
{
131
 
public:
132
113
  ha_rows records; /**< Number of processed records */
133
114
  ha_rows deleted; /**< Number of deleted records */
134
115
  ha_rows updated; /**< Number of updated records */
142
123
  List<Item> *update_fields;
143
124
  List<Item> *update_values;
144
125
  /* for VIEW ... WITH CHECK OPTION */
145
 
 
146
 
  CopyInfo() :
147
 
    records(0),
148
 
    deleted(0),
149
 
    updated(0),
150
 
    copied(0),
151
 
    error_count(0),
152
 
    touched(0),
153
 
    escape_char(0),
154
 
    last_errno(0),
155
 
    ignore(0),
156
 
    update_fields(0),
157
 
    update_values(0)
158
 
  { }
159
 
 
160
 
};
 
126
} COPY_INFO;
 
127
 
 
128
typedef struct drizzled_lock_st
 
129
{
 
130
  Table **table;
 
131
  uint32_t table_count;
 
132
  uint32_t lock_count;
 
133
  THR_LOCK_DATA **locks;
 
134
} DRIZZLE_LOCK;
161
135
 
162
136
} /* namespace drizzled */
163
137
 
173
147
#define Session_SENTRY_MAGIC 0xfeedd1ff
174
148
#define Session_SENTRY_GONE  0xdeadbeef
175
149
 
176
 
struct drizzle_system_variables
 
150
struct system_variables
177
151
{
178
 
  drizzle_system_variables()
179
 
  {}
 
152
  system_variables() {};
180
153
  /*
181
154
    How dynamically allocated system variables are handled:
182
155
 
213
186
  uint64_t preload_buff_size;
214
187
  uint32_t read_buff_size;
215
188
  uint32_t read_rnd_buff_size;
216
 
  bool replicate_query;
217
189
  size_t sortbuff_size;
218
190
  uint32_t thread_handling;
219
191
  uint32_t tx_isolation;
220
 
  size_t transaction_message_threshold;
221
192
  uint32_t completion_type;
222
193
  /* Determines which non-standard SQL behaviour should be enabled */
223
194
  uint32_t sql_mode;
247
218
  Time_zone *time_zone;
248
219
};
249
220
 
250
 
extern struct drizzle_system_variables global_system_variables;
 
221
extern struct system_variables global_system_variables;
251
222
 
252
223
} /* namespace drizzled */
253
224
 
258
229
 
259
230
void mark_transaction_to_rollback(Session *session, bool all);
260
231
 
 
232
extern pthread_mutex_t LOCK_xid_cache;
 
233
extern HASH xid_cache;
 
234
 
261
235
/**
262
236
  Storage engine specific thread local data.
263
237
*/
310
284
 * all member variables that are not critical to non-internal operations of the
311
285
 * session object.
312
286
 */
313
 
typedef int64_t session_id_t;
314
 
 
315
287
class Session : public Open_tables_state
316
288
{
317
289
public:
318
 
  // Plugin storage in Session.
319
 
  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
290
  /*
324
291
    MARK_COLUMNS_NONE:  Means mark_used_colums is not set and no indicator to
325
292
                        handler of fields used is set
376
343
  {
377
344
    return mem_root;
378
345
  }
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
346
  /**
393
347
   * Uniquely identifies each statement object in thread scope; change during
394
348
   * statement lifetime.
397
351
   */
398
352
  uint32_t id;
399
353
  LEX *lex; /**< parse tree descriptor */
400
 
 
401
 
  LEX *getLex() 
402
 
  {
403
 
    return lex;
404
 
  }
405
354
  /** 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
 
  }
 
355
  std::string query;
497
356
 
498
357
  /**
499
358
    Name of the current (default) database.
507
366
    the Session of that thread); that thread is (and must remain, for now) the
508
367
    only responsible for freeing this member.
509
368
  */
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;
522
 
  /* current cache key */
523
 
  std::string query_cache_key;
 
369
  std::string db;
 
370
 
524
371
  /**
525
372
    Constant for Session::where initialization in the beginning of every query.
526
373
 
531
378
 
532
379
  memory::Root warn_root; /**< Allocation area for warnings and errors */
533
380
  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
381
  plugin::Scheduler *scheduler; /**< Pointer to scheduler object */
543
382
  void *scheduler_arg; /**< Pointer to the optional scheduler argument */
544
 
 
545
 
  typedef boost::unordered_map< std::string, user_var_entry *, util::insensitive_hash, util::insensitive_equal_to> UserVars;
546
 
private:
547
 
  typedef std::pair< UserVars::iterator, UserVars::iterator > UserVarsRange;
548
 
  UserVars user_vars; /**< Hash of user variables defined during the session's lifetime */
549
 
 
550
 
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 */
 
383
  HASH user_vars; /**< Hash of user variables defined during the session's lifetime */
 
384
  struct system_variables variables; /**< Mutable local variables local to the session */
558
385
  struct system_status_var status_var; /**< Session-local status counters */
 
386
  struct system_status_var *initial_status_var; /* used by show status */
559
387
  THR_LOCK_INFO lock_info; /**< Locking information for this session */
560
388
  THR_LOCK_OWNER main_lock_id; /**< To use for conventional queries */
561
389
  THR_LOCK_OWNER *lock_id; /**< If not main_lock_id, points to the lock_id of a cursor. */
 
390
  pthread_mutex_t LOCK_delete; /**< Locked before session is deleted */
 
391
 
 
392
  /**
 
393
   * A peek into the query string for the session. This is a best effort
 
394
   * delivery, there is no guarantee whether the content is meaningful.
 
395
   */
 
396
  char process_list_info[PROCESS_LIST_WIDTH+1];
562
397
 
563
398
  /**
564
399
   * A pointer to the stack frame of the scheduler thread
567
402
  char *thread_stack;
568
403
 
569
404
private:
570
 
  identifier::User::shared_ptr security_ctx;
571
 
 
572
 
  int32_t scoreboard_index;
 
405
  SecurityContext security_ctx;
573
406
 
574
407
  inline void checkSentry() const
575
408
  {
576
409
    assert(this->dbug_sentry == Session_SENTRY_MAGIC);
577
410
  }
578
411
public:
579
 
  identifier::User::const_shared_ptr user() const
580
 
  {
581
 
    if (security_ctx)
582
 
      return security_ctx;
583
 
 
584
 
    return identifier::User::const_shared_ptr();
585
 
  }
586
 
 
587
 
  void setUser(identifier::User::shared_ptr arg)
588
 
  {
589
 
    security_ctx= arg;
590
 
  }
591
 
 
592
 
  int32_t getScoreboardIndex()
593
 
  {
594
 
    return scoreboard_index;
595
 
  }
596
 
 
597
 
  void setScoreboardIndex(int32_t in_scoreboard_index)
598
 
  {
599
 
    scoreboard_index= in_scoreboard_index;
 
412
  const SecurityContext& getSecurityContext() const
 
413
  {
 
414
    return security_ctx;
 
415
  }
 
416
 
 
417
  SecurityContext& getSecurityContext()
 
418
  {
 
419
    return security_ctx;
600
420
  }
601
421
 
602
422
  /**
603
423
   * Is this session viewable by the current user?
604
424
   */
605
 
  bool isViewable() const;
 
425
  bool isViewable() const
 
426
  {
 
427
    return plugin::Authorization::isAuthorized(current_session->getSecurityContext(),
 
428
                                               this,
 
429
                                               false);
 
430
  }
606
431
 
607
432
  /**
608
433
    Used in error messages to tell user in what part of MySQL we found an
617
442
    chapter 'Miscellaneous functions', for functions GET_LOCK, RELEASE_LOCK.
618
443
  */
619
444
  uint32_t dbug_sentry; /**< watch for memory corruption */
620
 
private:
621
 
  boost::thread::id boost_thread_id;
622
 
  boost_thread_shared_ptr _thread;
623
 
  boost::this_thread::disable_interruption *interrupt;
624
 
 
625
445
  internal::st_my_thread_var *mysys_var;
626
 
public:
627
 
 
628
 
  boost_thread_shared_ptr &getThread()
629
 
  {
630
 
    return _thread;
631
 
  }
632
 
 
633
 
  void pushInterrupt(boost::this_thread::disable_interruption *interrupt_arg)
634
 
  {
635
 
    interrupt= interrupt_arg;
636
 
  }
637
 
 
638
 
  boost::this_thread::disable_interruption &getThreadInterupt()
639
 
  {
640
 
    assert(interrupt);
641
 
    return *interrupt;
642
 
  }
643
 
 
644
 
  internal::st_my_thread_var *getThreadVar()
645
 
  {
646
 
    return mysys_var;
647
 
  }
648
 
 
649
446
  /**
650
447
   * Type of current query: COM_STMT_PREPARE, COM_QUERY, etc. Set from
651
448
   * first byte of the packet in executeStatement()
684
481
  ResourceContext *getResourceContext(const plugin::MonitoredInTransaction *monitored,
685
482
                                      size_t index= 0);
686
483
 
687
 
  /**
688
 
   * Structure used to manage "statement transactions" and
689
 
   * "normal transactions". In autocommit mode, the normal transaction is
690
 
   * equivalent to the statement transaction.
691
 
   *
692
 
   * Storage engines will be registered here when they participate in
693
 
   * a transaction. No engine is registered more than once.
694
 
   */
695
484
  struct st_transactions {
696
485
    std::deque<NamedSavepoint> savepoints;
697
 
 
698
 
    /**
699
 
     * The normal transaction (since BEGIN WORK).
700
 
     *
701
 
     * Contains a list of all engines that have participated in any of the
702
 
     * statement transactions started within the context of the normal
703
 
     * transaction.
704
 
     *
705
 
     * @note In autocommit mode, this is empty.
706
 
     */
707
 
    TransactionContext all;
708
 
 
709
 
    /**
710
 
     * The statment transaction.
711
 
     *
712
 
     * Contains a list of all engines participating in the given statement.
713
 
     *
714
 
     * @note In autocommit mode, this will be used to commit/rollback the
715
 
     * normal transaction.
716
 
     */
717
 
    TransactionContext stmt;
718
 
 
 
486
    TransactionContext all; ///< Trans since BEGIN WORK
 
487
    TransactionContext stmt; ///< Trans for current statement
719
488
    XID_STATE xid_state;
720
489
 
721
490
    void cleanup()
733
502
  Field *dup_field;
734
503
  sigset_t signals;
735
504
 
736
 
  // As of right now we do not allow a concurrent execute to launch itself
737
 
private:
738
 
  bool concurrent_execute_allowed;
739
 
public:
740
 
 
741
 
  void setConcurrentExecute(bool arg)
742
 
  {
743
 
    concurrent_execute_allowed= arg;
744
 
  }
745
 
 
746
 
  bool isConcurrentExecuteAllowed() const
747
 
  {
748
 
    return concurrent_execute_allowed;
749
 
  }
750
 
 
751
505
  /* Tells if LAST_INSERT_ID(#) was called for the current statement */
752
506
  bool arg_of_last_insert_id_function;
753
 
 
754
507
  /*
755
508
    ALL OVER THIS FILE, "insert_id" means "*automatically generated* value for
756
509
    insertion into an auto_increment column".
852
605
    create_sort_index(); may differ from examined_row_count.
853
606
  */
854
607
  uint32_t row_count;
855
 
  session_id_t thread_id;
 
608
  pthread_t real_id; /**< For debugging */
 
609
  uint64_t thread_id;
856
610
  uint32_t tmp_table;
857
 
  enum global_read_lock_t
858
 
  {
859
 
    NONE= 0,
860
 
    GOT_GLOBAL_READ_LOCK= 1,
861
 
    MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT= 2
862
 
  };
863
 
private:
864
 
  global_read_lock_t _global_read_lock;
865
 
 
866
 
public:
867
 
 
868
 
  global_read_lock_t isGlobalReadLock() const
869
 
  {
870
 
    return _global_read_lock;
871
 
  }
872
 
 
873
 
  void setGlobalReadLock(global_read_lock_t arg)
874
 
  {
875
 
    _global_read_lock= arg;
876
 
  }
877
 
 
878
 
  DrizzleLock *lockTables(Table **tables, uint32_t count, uint32_t flags, bool *need_reopen);
879
 
  bool lockGlobalReadLock();
880
 
  bool lock_table_names(TableList *table_list);
881
 
  bool lock_table_names_exclusively(TableList *table_list);
882
 
  bool makeGlobalReadLockBlockCommit();
883
 
  bool abortLockForThread(Table *table);
884
 
  bool wait_if_global_read_lock(bool abort_on_refresh, bool is_not_commit);
885
 
  int lock_table_name(TableList *table_list);
886
 
  void abortLock(Table *table);
887
 
  void removeLock(Table *table);
888
 
  void unlockReadTables(DrizzleLock *sql_lock);
889
 
  void unlockSomeTables(Table **table, uint32_t count);
890
 
  void unlockTables(DrizzleLock *sql_lock);
891
 
  void startWaitingGlobalReadLock();
892
 
  void unlockGlobalReadLock();
893
 
 
894
 
private:
895
 
  int unlock_external(Table **table, uint32_t count);
896
 
  int lock_external(Table **tables, uint32_t count);
897
 
  bool wait_for_locked_table_names(TableList *table_list);
898
 
  DrizzleLock *get_lock_data(Table **table_ptr, uint32_t count,
899
 
                             bool should_lock, Table **write_lock_used);
900
 
public:
901
 
 
 
611
  uint32_t global_read_lock;
902
612
  uint32_t server_status;
903
613
  uint32_t open_options;
904
614
  uint32_t select_number; /**< number of select (used for EXPLAIN) */
906
616
  enum_tx_isolation session_tx_isolation;
907
617
  enum_check_fields count_cuted_fields;
908
618
 
909
 
  enum killed_state_t
 
619
  enum killed_state
910
620
  {
911
621
    NOT_KILLED,
912
622
    KILL_BAD_DATA,
914
624
    KILL_QUERY,
915
625
    KILLED_NO_VALUE /* means none of the above states apply */
916
626
  };
917
 
private:
918
 
  killed_state_t volatile _killed;
919
 
 
920
 
public:
921
 
 
922
 
  void setKilled(killed_state_t arg)
923
 
  {
924
 
    _killed= arg;
925
 
  }
926
 
 
927
 
  killed_state_t getKilled()
928
 
  {
929
 
    return _killed;
930
 
  }
931
 
 
932
 
  volatile killed_state_t *getKilledPtr() // Do not use this method, it is here for historical convience.
933
 
  {
934
 
    return &_killed;
935
 
  }
936
 
 
937
 
  bool is_admin_connection;
 
627
  killed_state volatile killed;
 
628
 
938
629
  bool some_tables_deleted;
939
630
  bool no_errors;
940
631
  bool password;
1023
714
  }
1024
715
 
1025
716
  /** Returns the current query ID */
1026
 
  query_id_t getQueryId()  const
 
717
  inline query_id_t getQueryId()  const
1027
718
  {
1028
719
    return query_id;
1029
720
  }
1041
732
    return warn_query_id;
1042
733
  }
1043
734
 
 
735
  /** Returns the current query text */
 
736
  inline const std::string &getQueryString()  const
 
737
  {
 
738
    return query;
 
739
  }
 
740
 
 
741
  /** Returns the length of the current query text */
 
742
  inline size_t getQueryLength() const
 
743
  {
 
744
    if (! query.empty())
 
745
      return query.length();
 
746
    else
 
747
      return 0;
 
748
  }
 
749
 
1044
750
  /** Accessor method returning the session's ID. */
1045
 
  inline session_id_t getSessionId()  const
 
751
  inline uint64_t getSessionId()  const
1046
752
  {
1047
753
    return thread_id;
1048
754
  }
1133
839
   */
1134
840
  void cleanup_after_query();
1135
841
  bool storeGlobals();
1136
 
  void awake(Session::killed_state_t state_to_set);
 
842
  void awake(Session::killed_state state_to_set);
1137
843
  /**
1138
844
   * Pulls thread-specific variables into Session state.
1139
845
   *
1216
922
  /**
1217
923
   * Schedule a session to be run on the default scheduler.
1218
924
   */
1219
 
  static bool schedule(Session::shared_ptr&);
1220
 
 
1221
 
  static void unlink(Session::shared_ptr&);
 
925
  bool schedule();
1222
926
 
1223
927
  /*
1224
928
    For enter_cond() / exit_cond() to work the mutex must be got before
1225
929
    enter_cond(); this mutex is then released by exit_cond().
1226
930
    Usage must be: lock mutex; enter_cond(); your code; exit_cond().
1227
931
  */
1228
 
  const char* enter_cond(boost::condition_variable_any &cond, boost::mutex &mutex, const char* msg);
 
932
  const char* enter_cond(pthread_cond_t *cond, pthread_mutex_t* mutex, const char* msg);
1229
933
  void exit_cond(const char* old_msg);
1230
934
 
1231
935
  inline time_t query_start() { return start_time; }
1232
936
  inline void set_time()
1233
937
  {
1234
 
    boost::posix_time::ptime mytime(boost::posix_time::microsec_clock::local_time());
1235
 
    boost::posix_time::ptime epoch(boost::gregorian::date(1970,1,1));
1236
 
    start_utime= utime_after_lock= (mytime-epoch).total_microseconds();
1237
 
 
1238
938
    if (user_time)
1239
939
    {
1240
940
      start_time= user_time;
1241
 
      connect_microseconds= start_utime;
 
941
      connect_microseconds= start_utime= utime_after_lock= my_micro_time();
1242
942
    }
1243
 
    else 
1244
 
      start_time= (mytime-epoch).total_seconds();
 
943
    else
 
944
      start_utime= utime_after_lock= my_micro_time_and_time(&start_time);
1245
945
  }
1246
946
  inline void   set_current_time()    { start_time= time(NULL); }
1247
947
  inline void   set_time(time_t t)
1248
948
  {
1249
949
    start_time= user_time= t;
1250
 
    boost::posix_time::ptime mytime(boost::posix_time::microsec_clock::local_time());
1251
 
    boost::posix_time::ptime epoch(boost::gregorian::date(1970,1,1));
1252
 
    uint64_t t_mark= (mytime-epoch).total_microseconds();
1253
 
 
1254
 
    start_utime= utime_after_lock= t_mark;
1255
 
  }
1256
 
  void set_time_after_lock()  { 
1257
 
     boost::posix_time::ptime mytime(boost::posix_time::microsec_clock::local_time());
1258
 
     boost::posix_time::ptime epoch(boost::gregorian::date(1970,1,1));
1259
 
     utime_after_lock= (mytime-epoch).total_microseconds();
1260
 
  }
 
950
    start_utime= utime_after_lock= my_micro_time();
 
951
  }
 
952
  void set_time_after_lock()  { utime_after_lock= my_micro_time(); }
1261
953
  /**
1262
954
   * Returns the current micro-timestamp
1263
955
   */
1264
956
  inline uint64_t getCurrentTimestamp()  
1265
957
  { 
1266
 
    boost::posix_time::ptime mytime(boost::posix_time::microsec_clock::local_time());
1267
 
    boost::posix_time::ptime epoch(boost::gregorian::date(1970,1,1));
1268
 
    uint64_t t_mark= (mytime-epoch).total_microseconds();
1269
 
 
1270
 
    return t_mark; 
 
958
    return my_micro_time(); 
1271
959
  }
1272
960
  inline uint64_t found_rows(void)
1273
961
  {
1278
966
  {
1279
967
    return server_status & SERVER_STATUS_IN_TRANS;
1280
968
  }
 
969
  inline bool fill_derived_tables()
 
970
  {
 
971
    return !lex->only_view_structure();
 
972
  }
 
973
 
1281
974
  LEX_STRING *make_lex_string(LEX_STRING *lex_str,
1282
975
                              const char* str, uint32_t length,
1283
976
                              bool allocate_lex_string);
1293
986
    @todo: To silence an error, one should use Internal_error_handler
1294
987
    mechanism. In future this function will be removed.
1295
988
  */
1296
 
  inline void clear_error(bool full= false)
 
989
  inline void clear_error()
1297
990
  {
1298
991
    if (main_da.is_error())
1299
992
      main_da.reset_diagnostics_area();
1300
 
 
1301
 
    if (full)
1302
 
    {
1303
 
      drizzle_reset_errors(this, true);
1304
 
    }
1305
 
  }
1306
 
 
1307
 
  void clearDiagnostics()
1308
 
  {
1309
 
    main_da.reset_diagnostics_area();
 
993
    return;
1310
994
  }
1311
995
 
1312
996
  /**
1350
1034
  void end_statement();
1351
1035
  inline int killed_errno() const
1352
1036
  {
1353
 
    killed_state_t killed_val; /* to cache the volatile 'killed' */
1354
 
    return (killed_val= _killed) != KILL_BAD_DATA ? killed_val : 0;
 
1037
    killed_state killed_val; /* to cache the volatile 'killed' */
 
1038
    return (killed_val= killed) != KILL_BAD_DATA ? killed_val : 0;
1355
1039
  }
1356
1040
  void send_kill_message() const;
1357
1041
  /* return true if we will abort query if we make a warning now */
1359
1043
  {
1360
1044
    return (abort_on_warning);
1361
1045
  }
1362
 
 
1363
 
  void setAbort(bool arg);
1364
 
  void lockOnSys();
1365
1046
  void set_status_var_init();
1366
1047
 
1367
1048
  /**
1380
1061
    database usually involves other actions, like switching other database
1381
1062
    attributes including security context. In the future, this operation
1382
1063
    will be made private and more convenient interface will be provided.
 
1064
 
 
1065
    @return Operation status
 
1066
      @retval false Success
 
1067
      @retval true  Out-of-memory error
1383
1068
  */
1384
 
  void set_db(const std::string &new_db);
 
1069
  bool set_db(const std::string &new_db);
1385
1070
 
1386
1071
  /*
1387
1072
    Copy the current database to the argument. Use the current arena to
1446
1131
   * Current implementation does not depend on that, but future changes
1447
1132
   * should be done with this in mind; 
1448
1133
   *
1449
 
   * @param passwd Scrambled password received from client
1450
 
   * @param db Database name to connect to, may be NULL
 
1134
   * @param  Scrambled password received from client
 
1135
   * @param  Length of scrambled password
 
1136
   * @param  Database name to connect to, may be NULL
1451
1137
   */
1452
 
  bool checkUser(const std::string &passwd, const std::string &db);
 
1138
  bool checkUser(const char *passwd, uint32_t passwd_len, const char *db);
1453
1139
  
1454
1140
  /**
1455
1141
   * Returns the timestamp (in microseconds) of when the Session 
1478
1164
  {
1479
1165
    return statement_message;
1480
1166
  }
1481
 
  
1482
 
  /**
1483
 
   * Returns a pointer to the current Resulset message for this
1484
 
   * Session, or NULL if no active message.
1485
 
   */
1486
 
  message::Resultset *getResultsetMessage() const
1487
 
  {
1488
 
    return resultset;
1489
 
  }
 
1167
 
1490
1168
  /**
1491
1169
   * Sets the active transaction message used by the ReplicationServices
1492
1170
   * component.
1508
1186
  {
1509
1187
    statement_message= in_message;
1510
1188
  }
1511
 
 
1512
 
  /**
1513
 
   * Sets the active Resultset message used by the Query Cache
1514
 
   * plugin.
1515
 
   *
1516
 
   * @param[in] Pointer to the message
1517
 
   */
1518
 
  void setResultsetMessage(message::Resultset *in_message)
1519
 
  {
1520
 
    resultset= in_message;
1521
 
  }
1522
 
  /**
1523
 
   * reset the active Resultset message used by the Query Cache
1524
 
   * plugin.
1525
 
   */
1526
 
 
1527
 
  void resetResultsetMessage()
1528
 
  { 
1529
 
    resultset= NULL;
1530
 
  }
1531
 
 
1532
1189
private:
1533
1190
  /** Pointers to memory managed by the ReplicationServices component */
1534
1191
  message::Transaction *transaction_message;
1535
1192
  message::Statement *statement_message;
1536
 
  /* Pointer to the current resultset of Select query */
1537
 
  message::Resultset *resultset;
1538
1193
  plugin::EventObserverList *session_event_observers;
1539
1194
  
1540
1195
  /* Schema observers are mapped to databases. */
1620
1275
   * set to query_id of original query.
1621
1276
   */
1622
1277
  void mark_used_tables_as_free_for_reuse(Table *table);
 
1278
  /**
 
1279
    Mark all temporary tables which were used by the current statement or
 
1280
    substatement as free for reuse, but only if the query_id can be cleared.
 
1281
 
 
1282
    @param session thread context
 
1283
 
 
1284
    @remark For temp tables associated with a open SQL HANDLER the query_id
 
1285
            is not reset until the HANDLER is closed.
 
1286
  */
 
1287
  void mark_temp_tables_as_free_for_reuse();
1623
1288
 
1624
1289
public:
1625
1290
 
1661
1326
  }
1662
1327
  void refresh_status();
1663
1328
  user_var_entry *getVariable(LEX_STRING &name, bool create_if_not_exists);
1664
 
  user_var_entry *getVariable(const std::string  &name, bool create_if_not_exists);
1665
 
  void setVariable(const std::string &name, const std::string &value);
1666
1329
  
1667
1330
  /**
1668
1331
   * Closes all tables used by the current substatement, or all tables
1672
1335
  void close_old_data_files(bool morph_locks= false,
1673
1336
                            bool send_refresh= false);
1674
1337
  void close_open_tables();
1675
 
  void close_data_files_and_morph_locks(const TableIdentifier &identifier);
 
1338
  void close_data_files_and_morph_locks(TableIdentifier &identifier);
 
1339
  void close_data_files_and_morph_locks(const char *db, const char *table_name);
1676
1340
 
1677
1341
private:
1678
1342
  bool free_cached_table();
1703
1367
   */
1704
1368
  bool openTablesLock(TableList *tables);
1705
1369
 
 
1370
  /**
 
1371
   * Open all tables in list and process derived tables
 
1372
   *
 
1373
   * @param Pointer to a list of tables for open
 
1374
   * @param Bitmap of flags to modify how the tables will be open:
 
1375
   *        DRIZZLE_LOCK_IGNORE_FLUSH - open table even if someone has
 
1376
   *        done a flush or namelock on it.
 
1377
   *
 
1378
   * @retval
 
1379
   *  false - ok
 
1380
   * @retval
 
1381
   *  true  - error
 
1382
   *
 
1383
   * @note
 
1384
   *
 
1385
   * This is to be used on prepare stage when you don't read any
 
1386
   * data from the tables.
 
1387
   */
 
1388
  bool openTables(TableList *tables, uint32_t flags= 0);
 
1389
 
1706
1390
  int open_tables_from_list(TableList **start, uint32_t *counter, uint32_t flags= 0);
1707
1391
 
1708
1392
  Table *openTableLock(TableList *table_list, thr_lock_type lock_type);
1709
1393
  Table *openTable(TableList *table_list, bool *refresh, uint32_t flags= 0);
1710
1394
 
1711
1395
  void unlink_open_table(Table *find);
1712
 
  void drop_open_table(Table *table, const TableIdentifier &identifier);
 
1396
  void drop_open_table(Table *table, TableIdentifier &identifier);
1713
1397
  void close_cached_table(Table *table);
1714
1398
 
1715
1399
  /* Create a lock in the cache */
1716
 
  table::Placeholder *table_cache_insert_placeholder(const TableIdentifier &identifier);
1717
 
  bool lock_table_name_if_not_cached(const TableIdentifier &identifier, Table **table);
1718
 
 
1719
 
  typedef boost::unordered_map<std::string, message::Table, util::insensitive_hash, util::insensitive_equal_to> TableMessageCache;
1720
 
 
1721
 
  class TableMessages
1722
 
  {
1723
 
    TableMessageCache table_message_cache;
1724
 
 
1725
 
  public:
1726
 
    bool storeTableMessage(const TableIdentifier &identifier, message::Table &table_message);
1727
 
    bool removeTableMessage(const TableIdentifier &identifier);
1728
 
    bool getTableMessage(const TableIdentifier &identifier, message::Table &table_message);
1729
 
    bool doesTableMessageExist(const TableIdentifier &identifier);
1730
 
    bool renameTableMessage(const TableIdentifier &from, const TableIdentifier &to);
1731
 
 
1732
 
  };
 
1400
  Table *table_cache_insert_placeholder(const char *key, uint32_t key_length);
 
1401
  bool lock_table_name_if_not_cached(TableIdentifier &identifier, Table **table);
 
1402
  bool lock_table_name_if_not_cached(const char *db,
 
1403
                                     const char *table_name, Table **table);
 
1404
 
 
1405
  typedef unordered_map<std::string, message::Table> TableMessageCache;
 
1406
  TableMessageCache table_message_cache;
 
1407
 
 
1408
  bool storeTableMessage(TableIdentifier &identifier, message::Table &table_message);
 
1409
  bool removeTableMessage(TableIdentifier &identifier);
 
1410
  bool getTableMessage(TableIdentifier &identifier, message::Table &table_message);
 
1411
  bool doesTableMessageExist(TableIdentifier &identifier);
 
1412
  bool renameTableMessage(TableIdentifier &from, TableIdentifier &to);
 
1413
 
 
1414
  /* Work with temporary tables */
 
1415
  Table *find_temporary_table(TableList *table_list);
 
1416
  Table *find_temporary_table(const char *db, const char *table_name);
 
1417
  Table *find_temporary_table(TableIdentifier &identifier);
 
1418
 
 
1419
  void doGetTableNames(CachedDirectory &directory,
 
1420
                       SchemaIdentifier &schema_identifier,
 
1421
                       std::set<std::string>& set_of_names);
 
1422
  void doGetTableNames(SchemaIdentifier &schema_identifier,
 
1423
                       std::set<std::string>& set_of_names);
 
1424
 
 
1425
  void doGetTableIdentifiers(CachedDirectory &directory,
 
1426
                             SchemaIdentifier &schema_identifier,
 
1427
                             TableIdentifiers &set_of_identifiers);
 
1428
  void doGetTableIdentifiers(SchemaIdentifier &schema_identifier,
 
1429
                             TableIdentifiers &set_of_identifiers);
 
1430
 
 
1431
  int doGetTableDefinition(drizzled::TableIdentifier &identifier,
 
1432
                           message::Table &table_proto);
 
1433
  bool doDoesTableExist(TableIdentifier &identifier);
 
1434
 
 
1435
  void close_temporary_tables();
 
1436
  void close_temporary_table(Table *table);
 
1437
  // The method below just handles the de-allocation of the table. In
 
1438
  // a better memory type world, this would not be needed.
1733
1439
private:
1734
 
  TableMessages _table_message_cache;
1735
 
 
 
1440
  void nukeTable(Table *table);
1736
1441
public:
1737
 
  TableMessages &getMessageCache()
1738
 
  {
1739
 
    return _table_message_cache;
1740
 
  }
 
1442
 
 
1443
  void dumpTemporaryTableNames(const char *id);
 
1444
  int drop_temporary_table(TableList *table_list);
 
1445
  bool rm_temporary_table(plugin::StorageEngine *base, TableIdentifier &identifier);
 
1446
  bool rm_temporary_table(TableIdentifier &identifier);
 
1447
  Table *open_temporary_table(TableIdentifier &identifier,
 
1448
                              bool link_in_list= true);
1741
1449
 
1742
1450
  /* Reopen operations */
1743
1451
  bool reopen_tables(bool get_locks, bool mark_share_as_old);
 
1452
  bool reopen_name_locked_table(TableList* table_list, bool link_in);
1744
1453
  bool close_cached_tables(TableList *tables, bool wait_for_refresh, bool wait_for_placeholders);
1745
1454
 
1746
 
  void wait_for_condition(boost::mutex &mutex, boost::condition_variable_any &cond);
 
1455
  void wait_for_condition(pthread_mutex_t *mutex, pthread_cond_t *cond);
1747
1456
  int setup_conds(TableList *leaves, COND **conds);
1748
1457
  int lock_tables(TableList *tables, uint32_t count, bool *need_reopen);
1749
1458
 
1750
 
  drizzled::util::Storable *getProperty(const std::string &arg)
1751
 
  {
1752
 
    return life_properties[arg];
1753
 
  }
1754
 
 
1755
 
  template<class T>
1756
 
  bool setProperty(const std::string &arg, T *value)
1757
 
  {
1758
 
    life_properties[arg]= value;
1759
 
 
1760
 
    return true;
1761
 
  }
 
1459
  Table *create_virtual_tmp_table(List<CreateField> &field_list);
 
1460
 
 
1461
 
1762
1462
 
1763
1463
  /**
1764
1464
    Return the default storage engine
1773
1473
    if (variables.storage_engine)
1774
1474
      return variables.storage_engine;
1775
1475
    return global_system_variables.storage_engine;
1776
 
  }
 
1476
  };
 
1477
 
 
1478
  static void unlink(Session *session);
1777
1479
 
1778
1480
  void get_xid(DRIZZLE_XID *xid); // Innodb only
1779
1481
 
1780
 
  table::Instance *getInstanceTable();
1781
 
  table::Instance *getInstanceTable(List<CreateField> &field_list);
1782
 
 
1783
1482
private:
1784
 
  bool resetUsage()
1785
 
  {
1786
 
    if (getrusage(RUSAGE_THREAD, &usage))
1787
 
    {
1788
 
      return false;
1789
 
    }
 
1483
  std::vector<TableShareInstance *> temporary_shares;
1790
1484
 
1791
 
    return true;
1792
 
  }
1793
1485
public:
1794
 
 
1795
 
  void setUsage(bool arg)
1796
 
  {
1797
 
    use_usage= arg;
1798
 
  }
1799
 
 
1800
 
  const struct rusage &getUsage()
1801
 
  {
1802
 
    return usage;
1803
 
  }
1804
 
 
1805
 
private:
1806
 
  // This lives throughout the life of Session
1807
 
  bool use_usage;
1808
 
  PropertyMap life_properties;
1809
 
  std::vector<table::Instance *> temporary_shares;
1810
 
  struct rusage usage;
 
1486
  TableShareInstance *getTemporaryShare(const char *tmpname_arg);
 
1487
  TableShareInstance *getTemporaryShare();
1811
1488
};
1812
1489
 
1813
1490
class Join;
1836
1513
 * A structure used to describe sort information
1837
1514
 * for a field or item used in ORDER BY.
1838
1515
 */
1839
 
class SortField 
 
1516
typedef struct st_sort_field 
1840
1517
{
1841
 
public:
1842
1518
  Field *field; /**< Field to sort */
1843
1519
  Item  *item; /**< Item if not sorting fields */
1844
1520
  size_t length; /**< Length of sort field */
1846
1522
  Item_result result_type; /**< Type of item */
1847
1523
  bool reverse; /**< if descending sort */
1848
1524
  bool need_strxnfrm;   /**< If we have to use strxnfrm() */
1849
 
 
1850
 
  SortField() :
1851
 
    field(0),
1852
 
    item(0),
1853
 
    length(0),
1854
 
    suffix_length(0),
1855
 
    result_type(STRING_RESULT),
1856
 
    reverse(0),
1857
 
    need_strxnfrm(0)
1858
 
  { }
1859
 
 
1860
 
};
 
1525
} SORT_FIELD;
 
1526
 
 
1527
typedef struct st_sort_buffer 
 
1528
{
 
1529
  uint32_t index;       /* 0 or 1 */
 
1530
  uint32_t sort_orders;
 
1531
  uint32_t change_pos; /* If sort-fields changed */
 
1532
  char **buff;
 
1533
  SORT_FIELD *sortorder;
 
1534
} SORT_BUFFER;
1861
1535
 
1862
1536
} /* namespace drizzled */
1863
1537
 
1890
1564
static const std::bitset<CF_BIT_SIZE> CF_SHOW_TABLE_COMMAND(1 << CF_BIT_SHOW_TABLE_COMMAND);
1891
1565
static const std::bitset<CF_BIT_SIZE> CF_WRITE_LOGS_COMMAND(1 << CF_BIT_WRITE_LOGS_COMMAND);
1892
1566
 
1893
 
namespace display  {
1894
 
const std::string &type(drizzled::Session::global_read_lock_t type);
1895
 
size_t max_string_length(drizzled::Session::global_read_lock_t type);
1896
 
} /* namespace display */
 
1567
/* Functions in sql_class.cc */
 
1568
void add_to_status(system_status_var *to_var, system_status_var *from_var);
 
1569
 
 
1570
void add_diff_to_status(system_status_var *to_var, system_status_var *from_var,
 
1571
                        system_status_var *dec_var);
1897
1572
 
1898
1573
} /* namespace drizzled */
1899
1574