~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/handler.cc

  • Committer: mordred
  • Date: 2008-11-01 00:46:20 UTC
  • mto: (572.1.1 devel) (575.1.1 devel)
  • mto: This revision was merged to the branch mainline in revision 573.
  • Revision ID: mordred@opensolaris-20081101004620-vd0kzsl9k40hvf4p
Some updates to dtrace support.

Show diffs side-by-side

added added

removed removed

Lines of Context:
19
19
  Handler-calling-functions
20
20
*/
21
21
 
22
 
#ifdef USE_PRAGMA_IMPLEMENTATION
23
 
#pragma implementation                          // gcc: Class implementation
24
 
#endif
25
 
 
26
22
#include <drizzled/server_includes.h>
27
 
#include "rpl_filter.h"
28
 
#include <drizzled/drizzled_error_messages.h>
 
23
#include <drizzled/rpl_filter.h>
 
24
#include <drizzled/error.h>
 
25
#include <drizzled/gettext.h>
 
26
#include <drizzled/data_home.h>
 
27
#include <drizzled/probes.h>
 
28
#include <drizzled/sql_parse.h>
29
29
 
30
30
/*
31
31
  While we have legacy_db_type, we have this array to
36
36
 
37
37
static handlerton *installed_htons[128];
38
38
 
39
 
#define BITMAP_STACKBUF_SIZE (128/8)
40
 
 
41
39
KEY_CREATE_INFO default_key_create_info= { HA_KEY_ALG_UNDEF, 0, {NULL,0}, {NULL,0} };
42
40
 
43
41
/* number of entries in handlertons[] */
69
67
 
70
68
 
71
69
 
72
 
static plugin_ref ha_default_plugin(THD *thd)
 
70
static plugin_ref ha_default_plugin(Session *session)
73
71
{
74
 
  if (thd->variables.table_plugin)
75
 
    return thd->variables.table_plugin;
76
 
  return my_plugin_lock(thd, &global_system_variables.table_plugin);
 
72
  if (session->variables.table_plugin)
 
73
    return session->variables.table_plugin;
 
74
  return my_plugin_lock(session, &global_system_variables.table_plugin);
77
75
}
78
76
 
79
77
 
80
78
/**
81
79
  Return the default storage engine handlerton for thread
82
80
 
83
 
  @param ha_default_handlerton(thd)
84
 
  @param thd         current thread
 
81
  @param ha_default_handlerton(session)
 
82
  @param session         current thread
85
83
 
86
84
  @return
87
85
    pointer to handlerton
88
86
*/
89
 
handlerton *ha_default_handlerton(THD *thd)
 
87
handlerton *ha_default_handlerton(Session *session)
90
88
{
91
 
  plugin_ref plugin= ha_default_plugin(thd);
 
89
  plugin_ref plugin= ha_default_plugin(session);
92
90
  assert(plugin);
93
91
  handlerton *hton= plugin_data(plugin, handlerton*);
94
92
  assert(hton);
99
97
/**
100
98
  Return the storage engine handlerton for the supplied name
101
99
  
102
 
  @param thd         current thread
 
100
  @param session         current thread
103
101
  @param name        name of storage engine
104
102
  
105
103
  @return
106
104
    pointer to storage engine plugin handle
107
105
*/
108
 
plugin_ref ha_resolve_by_name(THD *thd, const LEX_STRING *name)
 
106
plugin_ref ha_resolve_by_name(Session *session, const LEX_STRING *name)
109
107
{
110
108
  const LEX_STRING *table_alias;
111
109
  plugin_ref plugin;
112
110
 
113
111
redo:
114
112
  /* my_strnncoll is a macro and gcc doesn't do early expansion of macro */
115
 
  if (thd && !my_charset_utf8_general_ci.coll->strnncoll(&my_charset_utf8_general_ci,
 
113
  if (session && !my_charset_utf8_general_ci.coll->strnncoll(&my_charset_utf8_general_ci,
116
114
                           (const unsigned char *)name->str, name->length,
117
115
                           (const unsigned char *)STRING_WITH_LEN("DEFAULT"), 0))
118
 
    return ha_default_plugin(thd);
 
116
    return ha_default_plugin(session);
119
117
 
120
 
  if ((plugin= my_plugin_lock_by_name(thd, name, DRIZZLE_STORAGE_ENGINE_PLUGIN)))
 
118
  if ((plugin= my_plugin_lock_by_name(session, name, DRIZZLE_STORAGE_ENGINE_PLUGIN)))
121
119
  {
122
120
    handlerton *hton= plugin_data(plugin, handlerton *);
123
121
    if (!(hton->flags & HTON_NOT_USER_SELECTABLE))
126
124
    /*
127
125
      unlocking plugin immediately after locking is relatively low cost.
128
126
    */
129
 
    plugin_unlock(thd, plugin);
 
127
    plugin_unlock(session, plugin);
130
128
  }
131
129
 
132
130
  /*
147
145
}
148
146
 
149
147
 
150
 
plugin_ref ha_lock_engine(THD *thd, handlerton *hton)
 
148
plugin_ref ha_lock_engine(Session *session, handlerton *hton)
151
149
{
152
150
  if (hton)
153
151
  {
154
152
    st_plugin_int **plugin= hton2plugin + hton->slot;
155
153
    
156
 
    return my_plugin_lock(thd, &plugin);
 
154
    return my_plugin_lock(session, &plugin);
157
155
  }
158
156
  return NULL;
159
157
}
160
158
 
161
159
 
162
 
handlerton *ha_resolve_by_legacy_type(THD *thd, enum legacy_db_type db_type)
 
160
handlerton *ha_resolve_by_legacy_type(Session *session, enum legacy_db_type db_type)
163
161
{
164
162
  plugin_ref plugin;
165
163
  switch (db_type) {
166
164
  case DB_TYPE_DEFAULT:
167
 
    return ha_default_handlerton(thd);
 
165
    return ha_default_handlerton(session);
168
166
  default:
169
167
    if (db_type > DB_TYPE_UNKNOWN && db_type < DB_TYPE_DEFAULT &&
170
 
        (plugin= ha_lock_engine(thd, installed_htons[db_type])))
 
168
        (plugin= ha_lock_engine(session, installed_htons[db_type])))
171
169
      return plugin_data(plugin, handlerton*);
172
170
    /* fall through */
173
171
  case DB_TYPE_UNKNOWN:
179
177
/**
180
178
  Use other database handler if databasehandler is not compiled in.
181
179
*/
182
 
handlerton *ha_checktype(THD *thd, enum legacy_db_type database_type,
 
180
handlerton *ha_checktype(Session *session, enum legacy_db_type database_type,
183
181
                          bool no_substitute, bool report_error)
184
182
{
185
 
  handlerton *hton= ha_resolve_by_legacy_type(thd, database_type);
 
183
  handlerton *hton= ha_resolve_by_legacy_type(session, database_type);
186
184
  if (ha_storage_engine_is_enabled(hton))
187
185
    return hton;
188
186
 
196
194
    return NULL;
197
195
  }
198
196
 
199
 
  return ha_default_handlerton(thd);
 
197
  return ha_default_handlerton(session);
200
198
} /* ha_checktype */
201
199
 
202
200
 
213
211
  }
214
212
  /*
215
213
    Try the default table type
216
 
    Here the call to current_thd() is ok as we call this function a lot of
 
214
    Here the call to current_session() is ok as we call this function a lot of
217
215
    times but we enter this branch very seldom.
218
216
  */
219
 
  return(get_new_handler(share, alloc, ha_default_handlerton(current_thd)));
 
217
  return(get_new_handler(share, alloc, ha_default_handlerton(current_session)));
220
218
}
221
219
 
222
220
 
450
448
  return(error);
451
449
}
452
450
 
453
 
static bool dropdb_handlerton(THD *unused1 __attribute__((unused)),
 
451
static bool dropdb_handlerton(Session *unused1 __attribute__((unused)),
454
452
                              plugin_ref plugin,
455
453
                              void *path)
456
454
{
467
465
}
468
466
 
469
467
 
470
 
static bool closecon_handlerton(THD *thd, plugin_ref plugin,
 
468
static bool closecon_handlerton(Session *session, plugin_ref plugin,
471
469
                                void *unused __attribute__((unused)))
472
470
{
473
471
  handlerton *hton= plugin_data(plugin, handlerton *);
476
474
    be rolled back already
477
475
  */
478
476
  if (hton->state == SHOW_OPTION_YES && hton->close_connection &&
479
 
      thd_get_ha_data(thd, hton))
480
 
    hton->close_connection(hton, thd);
 
477
      session_get_ha_data(session, hton))
 
478
    hton->close_connection(hton, session);
481
479
  return false;
482
480
}
483
481
 
486
484
  @note
487
485
    don't bother to rollback here, it's done already
488
486
*/
489
 
void ha_close_connection(THD* thd)
 
487
void ha_close_connection(Session* session)
490
488
{
491
 
  plugin_foreach(thd, closecon_handlerton, DRIZZLE_STORAGE_ENGINE_PLUGIN, 0);
 
489
  plugin_foreach(session, closecon_handlerton, DRIZZLE_STORAGE_ENGINE_PLUGIN, 0);
492
490
}
493
491
 
494
492
/* ========================================================================
593
591
  -----------
594
592
 
595
593
  The server stores its transaction-related data in
596
 
  thd->transaction. This structure has two members of type
597
 
  THD_TRANS. These members correspond to the statement and
 
594
  session->transaction. This structure has two members of type
 
595
  Session_TRANS. These members correspond to the statement and
598
596
  normal transactions respectively:
599
597
 
600
 
  - thd->transaction.stmt contains a list of engines
 
598
  - session->transaction.stmt contains a list of engines
601
599
  that are participating in the given statement
602
 
  - thd->transaction.all contains a list of engines that
 
600
  - session->transaction.all contains a list of engines that
603
601
  have participated in any of the statement transactions started
604
602
  within the context of the normal transaction.
605
603
  Each element of the list contains a pointer to the storage
606
604
  engine, engine-specific transactional data, and engine-specific
607
605
  transaction flags.
608
606
 
609
 
  In autocommit mode thd->transaction.all is empty.
610
 
  Instead, data of thd->transaction.stmt is
 
607
  In autocommit mode session->transaction.all is empty.
 
608
  Instead, data of session->transaction.stmt is
611
609
  used to commit/rollback the normal transaction.
612
610
 
613
611
  The list of registered engines has a few important properties:
618
616
  Transaction life cycle
619
617
  ----------------------
620
618
 
621
 
  When a new connection is established, thd->transaction
 
619
  When a new connection is established, session->transaction
622
620
  members are initialized to an empty state.
623
621
  If a statement uses any tables, all affected engines
624
622
  are registered in the statement engine list. In
634
632
  and emptied again at the next statement's end.
635
633
 
636
634
  The normal transaction is committed in a similar way
637
 
  (by going over all engines in thd->transaction.all list)
 
635
  (by going over all engines in session->transaction.all list)
638
636
  but at different times:
639
637
  - upon COMMIT SQL statement is issued by the user
640
638
  - implicitly, by the server, at the beginning of a DDL statement
644
642
  - if the user has requested so, by issuing ROLLBACK SQL
645
643
  statement
646
644
  - if one of the storage engines requested a rollback
647
 
  by setting thd->transaction_rollback_request. This may
 
645
  by setting session->transaction_rollback_request. This may
648
646
  happen in case, e.g., when the transaction in the engine was
649
647
  chosen a victim of the internal deadlock resolution algorithm
650
648
  and rolled back internally. When such a situation happens, there
686
684
  transactions of other participants.
687
685
 
688
686
  After the normal transaction has been committed,
689
 
  thd->transaction.all list is cleared.
 
687
  session->transaction.all list is cleared.
690
688
 
691
689
  When a connection is closed, the current normal transaction, if
692
690
  any, is rolled back.
750
748
  ---------------------------------------------------
751
749
 
752
750
  DDLs and operations with non-transactional engines
753
 
  do not "register" in thd->transaction lists, and thus do not
 
751
  do not "register" in session->transaction lists, and thus do not
754
752
  modify the transaction state. Besides, each DDL in
755
753
  MySQL is prefixed with an implicit normal transaction commit
756
754
  (a call to end_active_trans()), and thus leaves nothing
797
795
    times per transaction.
798
796
 
799
797
*/
800
 
void trans_register_ha(THD *thd, bool all, handlerton *ht_arg)
 
798
void trans_register_ha(Session *session, bool all, handlerton *ht_arg)
801
799
{
802
 
  THD_TRANS *trans;
 
800
  Session_TRANS *trans;
803
801
  Ha_trx_info *ha_info;
804
802
 
805
803
  if (all)
806
804
  {
807
 
    trans= &thd->transaction.all;
808
 
    thd->server_status|= SERVER_STATUS_IN_TRANS;
 
805
    trans= &session->transaction.all;
 
806
    session->server_status|= SERVER_STATUS_IN_TRANS;
809
807
  }
810
808
  else
811
 
    trans= &thd->transaction.stmt;
 
809
    trans= &session->transaction.stmt;
812
810
 
813
 
  ha_info= thd->ha_data[ht_arg->slot].ha_info + static_cast<unsigned>(all);
 
811
  ha_info= session->ha_data[ht_arg->slot].ha_info + static_cast<unsigned>(all);
814
812
 
815
813
  if (ha_info->is_started())
816
814
    return; /* already registered, return */
818
816
  ha_info->register_ha(trans, ht_arg);
819
817
 
820
818
  trans->no_2pc|=(ht_arg->prepare==0);
821
 
  if (thd->transaction.xid_state.xid.is_null())
822
 
    thd->transaction.xid_state.xid.set(thd->query_id);
 
819
  if (session->transaction.xid_state.xid.is_null())
 
820
    session->transaction.xid_state.xid.set(session->query_id);
823
821
 
824
822
  return;
825
823
}
830
828
  @retval
831
829
    1   error, transaction was rolled back
832
830
*/
833
 
int ha_prepare(THD *thd)
 
831
int ha_prepare(Session *session)
834
832
{
835
833
  int error=0, all=1;
836
 
  THD_TRANS *trans=all ? &thd->transaction.all : &thd->transaction.stmt;
 
834
  Session_TRANS *trans=all ? &session->transaction.all : &session->transaction.stmt;
837
835
  Ha_trx_info *ha_info= trans->ha_list;
838
836
  if (ha_info)
839
837
  {
841
839
    {
842
840
      int err;
843
841
      handlerton *ht= ha_info->ht();
844
 
      status_var_increment(thd->status_var.ha_prepare_count);
 
842
      status_var_increment(session->status_var.ha_prepare_count);
845
843
      if (ht->prepare)
846
844
      {
847
 
        if ((err= ht->prepare(ht, thd, all)))
 
845
        if ((err= ht->prepare(ht, session, all)))
848
846
        {
849
847
          my_error(ER_ERROR_DURING_COMMIT, MYF(0), err);
850
 
          ha_rollback_trans(thd, all);
 
848
          ha_rollback_trans(session, all);
851
849
          error=1;
852
850
          break;
853
851
        }
854
852
      }
855
853
      else
856
854
      {
857
 
        push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
855
        push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
858
856
                            ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
859
857
                            ha_resolve_storage_engine_name(ht));
860
858
      }
879
877
 
880
878
static
881
879
bool
882
 
ha_check_and_coalesce_trx_read_only(THD *thd, Ha_trx_info *ha_list,
 
880
ha_check_and_coalesce_trx_read_only(Session *session, Ha_trx_info *ha_list,
883
881
                                    bool all)
884
882
{
885
883
  /* The number of storage engines that have actual changes. */
893
891
 
894
892
    if (! all)
895
893
    {
896
 
      Ha_trx_info *ha_info_all= &thd->ha_data[ha_info->ht()->slot].ha_info[1];
 
894
      Ha_trx_info *ha_info_all= &session->ha_data[ha_info->ht()->slot].ha_info[1];
897
895
      assert(ha_info != ha_info_all);
898
896
      /*
899
897
        Merge read-only/read-write information about statement
900
898
        transaction to its enclosing normal transaction. Do this
901
899
        only if in a real transaction -- that is, if we know
902
 
        that ha_info_all is registered in thd->transaction.all.
 
900
        that ha_info_all is registered in session->transaction.all.
903
901
        Since otherwise we only clutter the normal transaction flags.
904
902
      */
905
903
      if (ha_info_all->is_started()) /* false if autocommit. */
933
931
    stored functions or triggers. So we simply do nothing now.
934
932
    TODO: This should be fixed in later ( >= 5.1) releases.
935
933
*/
936
 
int ha_commit_trans(THD *thd, bool all)
 
934
int ha_commit_trans(Session *session, bool all)
937
935
{
938
936
  int error= 0, cookie= 0;
939
937
  /*
940
938
    'all' means that this is either an explicit commit issued by
941
939
    user, or an implicit commit issued by a DDL.
942
940
  */
943
 
  THD_TRANS *trans= all ? &thd->transaction.all : &thd->transaction.stmt;
944
 
  bool is_real_trans= all || thd->transaction.all.ha_list == 0;
 
941
  Session_TRANS *trans= all ? &session->transaction.all : &session->transaction.stmt;
 
942
  bool is_real_trans= all || session->transaction.all.ha_list == 0;
945
943
  Ha_trx_info *ha_info= trans->ha_list;
946
 
  my_xid xid= thd->transaction.xid_state.xid.get_my_xid();
 
944
  my_xid xid= session->transaction.xid_state.xid.get_my_xid();
947
945
 
948
946
  /*
949
947
    We must not commit the normal transaction if a statement
951
949
    flags will not get propagated to its normal transaction's
952
950
    counterpart.
953
951
  */
954
 
  assert(thd->transaction.stmt.ha_list == NULL ||
955
 
              trans == &thd->transaction.stmt);
 
952
  assert(session->transaction.stmt.ha_list == NULL ||
 
953
              trans == &session->transaction.stmt);
956
954
 
957
 
  if (thd->in_sub_stmt)
958
 
  {
959
 
    /*
960
 
      Since we don't support nested statement transactions in 5.0,
961
 
      we can't commit or rollback stmt transactions while we are inside
962
 
      stored functions or triggers. So we simply do nothing now.
963
 
      TODO: This should be fixed in later ( >= 5.1) releases.
964
 
    */
965
 
    if (!all)
966
 
      return(0);
967
 
    /*
968
 
      We assume that all statements which commit or rollback main transaction
969
 
      are prohibited inside of stored functions or triggers. So they should
970
 
      bail out with error even before ha_commit_trans() call. To be 100% safe
971
 
      let us throw error in non-debug builds.
972
 
    */
973
 
    assert(0);
974
 
    my_error(ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0));
975
 
    return(2);
976
 
  }
977
955
  if (ha_info)
978
956
  {
979
957
    bool must_2pc;
980
958
 
981
 
    if (is_real_trans && wait_if_global_read_lock(thd, 0, 0))
 
959
    if (is_real_trans && wait_if_global_read_lock(session, 0, 0))
982
960
    {
983
 
      ha_rollback_trans(thd, all);
 
961
      ha_rollback_trans(session, all);
984
962
      return(1);
985
963
    }
986
964
 
987
965
    if (   is_real_trans
988
966
        && opt_readonly
989
 
        && ! thd->slave_thread
 
967
        && ! session->slave_thread
990
968
       )
991
969
    {
992
970
      my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--read-only");
993
 
      ha_rollback_trans(thd, all);
 
971
      ha_rollback_trans(session, all);
994
972
      error= 1;
995
973
      goto end;
996
974
    }
997
975
 
998
 
    must_2pc= ha_check_and_coalesce_trx_read_only(thd, ha_info, all);
 
976
    must_2pc= ha_check_and_coalesce_trx_read_only(session, ha_info, all);
999
977
 
1000
978
    if (!trans->no_2pc && must_2pc)
1001
979
    {
1014
992
          Sic: we know that prepare() is not NULL since otherwise
1015
993
          trans->no_2pc would have been set.
1016
994
        */
1017
 
        if ((err= ht->prepare(ht, thd, all)))
 
995
        if ((err= ht->prepare(ht, session, all)))
1018
996
        {
1019
997
          my_error(ER_ERROR_DURING_COMMIT, MYF(0), err);
1020
998
          error= 1;
1021
999
        }
1022
 
        status_var_increment(thd->status_var.ha_prepare_count);
 
1000
        status_var_increment(session->status_var.ha_prepare_count);
1023
1001
      }
1024
1002
      if (error || (is_real_trans && xid &&
1025
 
                    (error= !(cookie= tc_log->log_xid(thd, xid)))))
 
1003
                    (error= !(cookie= tc_log->log_xid(session, xid)))))
1026
1004
      {
1027
 
        ha_rollback_trans(thd, all);
 
1005
        ha_rollback_trans(session, all);
1028
1006
        error= 1;
1029
1007
        goto end;
1030
1008
      }
1031
1009
    }
1032
 
    error=ha_commit_one_phase(thd, all) ? (cookie ? 2 : 1) : 0;
 
1010
    error=ha_commit_one_phase(session, all) ? (cookie ? 2 : 1) : 0;
1033
1011
    if (cookie)
1034
1012
      tc_log->unlog(cookie, xid);
1035
1013
end:
1036
1014
    if (is_real_trans)
1037
 
      start_waiting_global_read_lock(thd);
 
1015
      start_waiting_global_read_lock(session);
1038
1016
  }
1039
1017
  return(error);
1040
1018
}
1043
1021
  @note
1044
1022
  This function does not care about global read lock. A caller should.
1045
1023
*/
1046
 
int ha_commit_one_phase(THD *thd, bool all)
 
1024
int ha_commit_one_phase(Session *session, bool all)
1047
1025
{
1048
1026
  int error=0;
1049
 
  THD_TRANS *trans=all ? &thd->transaction.all : &thd->transaction.stmt;
1050
 
  bool is_real_trans=all || thd->transaction.all.ha_list == 0;
 
1027
  Session_TRANS *trans=all ? &session->transaction.all : &session->transaction.stmt;
 
1028
  bool is_real_trans=all || session->transaction.all.ha_list == 0;
1051
1029
  Ha_trx_info *ha_info= trans->ha_list, *ha_info_next;
1052
1030
  if (ha_info)
1053
1031
  {
1055
1033
    {
1056
1034
      int err;
1057
1035
      handlerton *ht= ha_info->ht();
1058
 
      if ((err= ht->commit(ht, thd, all)))
 
1036
      if ((err= ht->commit(ht, session, all)))
1059
1037
      {
1060
1038
        my_error(ER_ERROR_DURING_COMMIT, MYF(0), err);
1061
1039
        error=1;
1062
1040
      }
1063
 
      status_var_increment(thd->status_var.ha_commit_count);
 
1041
      status_var_increment(session->status_var.ha_commit_count);
1064
1042
      ha_info_next= ha_info->next();
1065
1043
      ha_info->reset(); /* keep it conveniently zero-filled */
1066
1044
    }
1067
1045
    trans->ha_list= 0;
1068
1046
    trans->no_2pc=0;
1069
1047
    if (is_real_trans)
1070
 
      thd->transaction.xid_state.xid.null();
 
1048
      session->transaction.xid_state.xid.null();
1071
1049
    if (all)
1072
1050
    {
1073
 
      thd->variables.tx_isolation=thd->session_tx_isolation;
1074
 
      thd->transaction.cleanup();
 
1051
      session->variables.tx_isolation=session->session_tx_isolation;
 
1052
      session->transaction.cleanup();
1075
1053
    }
1076
1054
  }
1077
1055
  return(error);
1078
1056
}
1079
1057
 
1080
1058
 
1081
 
int ha_rollback_trans(THD *thd, bool all)
 
1059
int ha_rollback_trans(Session *session, bool all)
1082
1060
{
1083
1061
  int error=0;
1084
 
  THD_TRANS *trans=all ? &thd->transaction.all : &thd->transaction.stmt;
 
1062
  Session_TRANS *trans=all ? &session->transaction.all : &session->transaction.stmt;
1085
1063
  Ha_trx_info *ha_info= trans->ha_list, *ha_info_next;
1086
 
  bool is_real_trans=all || thd->transaction.all.ha_list == 0;
 
1064
  bool is_real_trans=all || session->transaction.all.ha_list == 0;
1087
1065
 
1088
1066
  /*
1089
1067
    We must not rollback the normal transaction if a statement
1090
1068
    transaction is pending.
1091
1069
  */
1092
 
  assert(thd->transaction.stmt.ha_list == NULL ||
1093
 
              trans == &thd->transaction.stmt);
 
1070
  assert(session->transaction.stmt.ha_list == NULL ||
 
1071
              trans == &session->transaction.stmt);
1094
1072
 
1095
 
  if (thd->in_sub_stmt)
1096
 
  {
1097
 
    /*
1098
 
      If we are inside stored function or trigger we should not commit or
1099
 
      rollback current statement transaction. See comment in ha_commit_trans()
1100
 
      call for more information.
1101
 
    */
1102
 
    if (!all)
1103
 
      return(0);
1104
 
    assert(0);
1105
 
    my_error(ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0));
1106
 
    return(1);
1107
 
  }
1108
1073
  if (ha_info)
1109
1074
  {
1110
1075
    for (; ha_info; ha_info= ha_info_next)
1111
1076
    {
1112
1077
      int err;
1113
1078
      handlerton *ht= ha_info->ht();
1114
 
      if ((err= ht->rollback(ht, thd, all)))
 
1079
      if ((err= ht->rollback(ht, session, all)))
1115
1080
      { // cannot happen
1116
1081
        my_error(ER_ERROR_DURING_ROLLBACK, MYF(0), err);
1117
1082
        error=1;
1118
1083
      }
1119
 
      status_var_increment(thd->status_var.ha_rollback_count);
 
1084
      status_var_increment(session->status_var.ha_rollback_count);
1120
1085
      ha_info_next= ha_info->next();
1121
1086
      ha_info->reset(); /* keep it conveniently zero-filled */
1122
1087
    }
1123
1088
    trans->ha_list= 0;
1124
1089
    trans->no_2pc=0;
1125
1090
    if (is_real_trans)
1126
 
      thd->transaction.xid_state.xid.null();
 
1091
      session->transaction.xid_state.xid.null();
1127
1092
    if (all)
1128
1093
    {
1129
 
      thd->variables.tx_isolation=thd->session_tx_isolation;
1130
 
      thd->transaction.cleanup();
 
1094
      session->variables.tx_isolation=session->session_tx_isolation;
 
1095
      session->transaction.cleanup();
1131
1096
    }
1132
1097
  }
1133
1098
  if (all)
1134
 
    thd->transaction_rollback_request= false;
 
1099
    session->transaction_rollback_request= false;
1135
1100
 
1136
1101
  /*
1137
1102
    If a non-transactional table was updated, warn; don't warn if this is a
1142
1107
    the error log; but we don't want users to wonder why they have this
1143
1108
    message in the error log, so we don't send it.
1144
1109
  */
1145
 
  if (is_real_trans && thd->transaction.all.modified_non_trans_table &&
1146
 
      !thd->slave_thread && thd->killed != THD::KILL_CONNECTION)
1147
 
    push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
1110
  if (is_real_trans && session->transaction.all.modified_non_trans_table &&
 
1111
      !session->slave_thread && session->killed != Session::KILL_CONNECTION)
 
1112
    push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
1148
1113
                 ER_WARNING_NOT_COMPLETE_ROLLBACK,
1149
1114
                 ER(ER_WARNING_NOT_COMPLETE_ROLLBACK));
1150
1115
  return(error);
1161
1126
    the user has used LOCK TABLES then that mechanism does not know to do the
1162
1127
    commit.
1163
1128
*/
1164
 
int ha_autocommit_or_rollback(THD *thd, int error)
 
1129
int ha_autocommit_or_rollback(Session *session, int error)
1165
1130
{
1166
 
  if (thd->transaction.stmt.ha_list)
 
1131
  if (session->transaction.stmt.ha_list)
1167
1132
  {
1168
1133
    if (!error)
1169
1134
    {
1170
 
      if (ha_commit_trans(thd, 0))
 
1135
      if (ha_commit_trans(session, 0))
1171
1136
        error=1;
1172
1137
    }
1173
1138
    else 
1174
1139
    {
1175
 
      (void) ha_rollback_trans(thd, 0);
1176
 
      if (thd->transaction_rollback_request && !thd->in_sub_stmt)
1177
 
        (void) ha_rollback(thd);
 
1140
      (void) ha_rollback_trans(session, 0);
 
1141
      if (session->transaction_rollback_request)
 
1142
        (void) ha_rollback(session);
1178
1143
    }
1179
1144
 
1180
 
    thd->variables.tx_isolation=thd->session_tx_isolation;
 
1145
    session->variables.tx_isolation=session->session_tx_isolation;
1181
1146
  }
1182
1147
  return(error);
1183
1148
}
1188
1153
  int result;
1189
1154
};
1190
1155
 
1191
 
static bool xacommit_handlerton(THD *unused1 __attribute__((unused)),
 
1156
static bool xacommit_handlerton(Session *unused1 __attribute__((unused)),
1192
1157
                                plugin_ref plugin,
1193
1158
                                void *arg)
1194
1159
{
1201
1166
  return false;
1202
1167
}
1203
1168
 
1204
 
static bool xarollback_handlerton(THD *unused1 __attribute__((unused)),
 
1169
static bool xarollback_handlerton(Session *unused1 __attribute__((unused)),
1205
1170
                                  plugin_ref plugin,
1206
1171
                                  void *arg)
1207
1172
{
1251
1216
  bool dry_run;
1252
1217
};
1253
1218
 
1254
 
static bool xarecover_handlerton(THD *unused __attribute__((unused)),
 
1219
static bool xarecover_handlerton(Session *unused __attribute__((unused)),
1255
1220
                                 plugin_ref plugin,
1256
1221
                                 void *arg)
1257
1222
{
1373
1338
    so mysql_xa_recover does not filter XID's to ensure uniqueness.
1374
1339
    It can be easily fixed later, if necessary.
1375
1340
*/
1376
 
bool mysql_xa_recover(THD *thd)
 
1341
bool mysql_xa_recover(Session *session)
1377
1342
{
1378
1343
  List<Item> field_list;
1379
 
  Protocol *protocol= thd->protocol;
 
1344
  Protocol *protocol= session->protocol;
1380
1345
  int i=0;
1381
1346
  XID_STATE *xs;
1382
1347
 
1409
1374
  }
1410
1375
 
1411
1376
  pthread_mutex_unlock(&LOCK_xid_cache);
1412
 
  my_eof(thd);
 
1377
  my_eof(session);
1413
1378
  return(0);
1414
1379
}
1415
1380
 
1417
1382
  @details
1418
1383
  This function should be called when MySQL sends rows of a SELECT result set
1419
1384
  or the EOF mark to the client. It releases a possible adaptive hash index
1420
 
  S-latch held by thd in InnoDB and also releases a possible InnoDB query
1421
 
  FIFO ticket to enter InnoDB. To save CPU time, InnoDB allows a thd to
 
1385
  S-latch held by session in InnoDB and also releases a possible InnoDB query
 
1386
  FIFO ticket to enter InnoDB. To save CPU time, InnoDB allows a session to
1422
1387
  keep them over several calls of the InnoDB handler interface when a join
1423
1388
  is executed. But when we let the control to pass to the client they have
1424
1389
  to be released because if the application program uses mysql_use_result(),
1426
1391
  performs another SQL query. In MySQL-4.1 this is even more important because
1427
1392
  there a connection can have several SELECT queries open at the same time.
1428
1393
 
1429
 
  @param thd           the thread handle of the current connection
 
1394
  @param session           the thread handle of the current connection
1430
1395
 
1431
1396
  @return
1432
1397
    always 0
1433
1398
*/
1434
 
static bool release_temporary_latches(THD *thd, plugin_ref plugin,
 
1399
static bool release_temporary_latches(Session *session, plugin_ref plugin,
1435
1400
                                      void *unused __attribute__((unused)))
1436
1401
{
1437
1402
  handlerton *hton= plugin_data(plugin, handlerton *);
1438
1403
 
1439
1404
  if (hton->state == SHOW_OPTION_YES && hton->release_temporary_latches)
1440
 
    hton->release_temporary_latches(hton, thd);
 
1405
    hton->release_temporary_latches(hton, session);
1441
1406
 
1442
1407
  return false;
1443
1408
}
1444
1409
 
1445
1410
 
1446
 
int ha_release_temporary_latches(THD *thd)
 
1411
int ha_release_temporary_latches(Session *session)
1447
1412
{
1448
 
  plugin_foreach(thd, release_temporary_latches, DRIZZLE_STORAGE_ENGINE_PLUGIN, 
 
1413
  plugin_foreach(session, release_temporary_latches, DRIZZLE_STORAGE_ENGINE_PLUGIN, 
1449
1414
                 NULL);
1450
1415
 
1451
1416
  return 0;
1452
1417
}
1453
1418
 
1454
 
int ha_rollback_to_savepoint(THD *thd, SAVEPOINT *sv)
 
1419
int ha_rollback_to_savepoint(Session *session, SAVEPOINT *sv)
1455
1420
{
1456
1421
  int error=0;
1457
 
  THD_TRANS *trans= (thd->in_sub_stmt ? &thd->transaction.stmt :
1458
 
                                        &thd->transaction.all);
 
1422
  Session_TRANS *trans= &session->transaction.all;
1459
1423
  Ha_trx_info *ha_info, *ha_info_next;
1460
1424
 
1461
1425
  trans->no_2pc=0;
1469
1433
    handlerton *ht= ha_info->ht();
1470
1434
    assert(ht);
1471
1435
    assert(ht->savepoint_set != 0);
1472
 
    if ((err= ht->savepoint_rollback(ht, thd,
 
1436
    if ((err= ht->savepoint_rollback(ht, session,
1473
1437
                                     (unsigned char *)(sv+1)+ht->savepoint_offset)))
1474
1438
    { // cannot happen
1475
1439
      my_error(ER_ERROR_DURING_ROLLBACK, MYF(0), err);
1476
1440
      error=1;
1477
1441
    }
1478
 
    status_var_increment(thd->status_var.ha_savepoint_rollback_count);
 
1442
    status_var_increment(session->status_var.ha_savepoint_rollback_count);
1479
1443
    trans->no_2pc|= ht->prepare == 0;
1480
1444
  }
1481
1445
  /*
1487
1451
  {
1488
1452
    int err;
1489
1453
    handlerton *ht= ha_info->ht();
1490
 
    if ((err= ht->rollback(ht, thd, !thd->in_sub_stmt)))
 
1454
    if ((err= ht->rollback(ht, session, !(0))))
1491
1455
    { // cannot happen
1492
1456
      my_error(ER_ERROR_DURING_ROLLBACK, MYF(0), err);
1493
1457
      error=1;
1494
1458
    }
1495
 
    status_var_increment(thd->status_var.ha_rollback_count);
 
1459
    status_var_increment(session->status_var.ha_rollback_count);
1496
1460
    ha_info_next= ha_info->next();
1497
1461
    ha_info->reset(); /* keep it conveniently zero-filled */
1498
1462
  }
1506
1470
  section "4.33.4 SQL-statements and transaction states",
1507
1471
  SAVEPOINT is *not* transaction-initiating SQL-statement
1508
1472
*/
1509
 
int ha_savepoint(THD *thd, SAVEPOINT *sv)
 
1473
int ha_savepoint(Session *session, SAVEPOINT *sv)
1510
1474
{
1511
1475
  int error=0;
1512
 
  THD_TRANS *trans= (thd->in_sub_stmt ? &thd->transaction.stmt :
1513
 
                                        &thd->transaction.all);
 
1476
  Session_TRANS *trans= &session->transaction.all;
1514
1477
  Ha_trx_info *ha_info= trans->ha_list;
1515
1478
  for (; ha_info; ha_info= ha_info->next())
1516
1479
  {
1523
1486
      error=1;
1524
1487
      break;
1525
1488
    }
1526
 
    if ((err= ht->savepoint_set(ht, thd, (unsigned char *)(sv+1)+ht->savepoint_offset)))
 
1489
    if ((err= ht->savepoint_set(ht, session, (unsigned char *)(sv+1)+ht->savepoint_offset)))
1527
1490
    { // cannot happen
1528
1491
      my_error(ER_GET_ERRNO, MYF(0), err);
1529
1492
      error=1;
1530
1493
    }
1531
 
    status_var_increment(thd->status_var.ha_savepoint_count);
 
1494
    status_var_increment(session->status_var.ha_savepoint_count);
1532
1495
  }
1533
1496
  /*
1534
1497
    Remember the list of registered storage engines. All new
1538
1501
  return(error);
1539
1502
}
1540
1503
 
1541
 
int ha_release_savepoint(THD *thd, SAVEPOINT *sv)
 
1504
int ha_release_savepoint(Session *session, SAVEPOINT *sv)
1542
1505
{
1543
1506
  int error=0;
1544
1507
  Ha_trx_info *ha_info= sv->ha_list;
1551
1514
    assert(ht);
1552
1515
    if (!ht->savepoint_release)
1553
1516
      continue;
1554
 
    if ((err= ht->savepoint_release(ht, thd,
 
1517
    if ((err= ht->savepoint_release(ht, session,
1555
1518
                                    (unsigned char *)(sv+1) + ht->savepoint_offset)))
1556
1519
    { // cannot happen
1557
1520
      my_error(ER_GET_ERRNO, MYF(0), err);
1562
1525
}
1563
1526
 
1564
1527
 
1565
 
static bool snapshot_handlerton(THD *thd, plugin_ref plugin, void *arg)
 
1528
static bool snapshot_handlerton(Session *session, plugin_ref plugin, void *arg)
1566
1529
{
1567
1530
  handlerton *hton= plugin_data(plugin, handlerton *);
1568
1531
  if (hton->state == SHOW_OPTION_YES &&
1569
1532
      hton->start_consistent_snapshot)
1570
1533
  {
1571
 
    hton->start_consistent_snapshot(hton, thd);
 
1534
    hton->start_consistent_snapshot(hton, session);
1572
1535
    *((bool *)arg)= false;
1573
1536
  }
1574
1537
  return false;
1575
1538
}
1576
1539
 
1577
 
int ha_start_consistent_snapshot(THD *thd)
 
1540
int ha_start_consistent_snapshot(Session *session)
1578
1541
{
1579
1542
  bool warn= true;
1580
1543
 
1581
 
  plugin_foreach(thd, snapshot_handlerton, DRIZZLE_STORAGE_ENGINE_PLUGIN, &warn);
 
1544
  plugin_foreach(session, snapshot_handlerton, DRIZZLE_STORAGE_ENGINE_PLUGIN, &warn);
1582
1545
 
1583
1546
  /*
1584
1547
    Same idea as when one wants to CREATE TABLE in one engine which does not
1585
1548
    exist:
1586
1549
  */
1587
1550
  if (warn)
1588
 
    push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
 
1551
    push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
1589
1552
                 "This MySQL server does not support any "
1590
1553
                 "consistent-read capable storage engine");
1591
1554
  return 0;
1592
1555
}
1593
1556
 
1594
1557
 
1595
 
static bool flush_handlerton(THD *thd __attribute__((unused)),
 
1558
static bool flush_handlerton(Session *session __attribute__((unused)),
1596
1559
                             plugin_ref plugin,
1597
1560
                             void *arg __attribute__((unused)))
1598
1561
{
1652
1615
  virtual bool handle_error(uint32_t sql_errno,
1653
1616
                            const char *message,
1654
1617
                            DRIZZLE_ERROR::enum_warning_level level,
1655
 
                            THD *thd);
 
1618
                            Session *session);
1656
1619
  char buff[DRIZZLE_ERRMSG_SIZE];
1657
1620
};
1658
1621
 
1662
1625
handle_error(uint32_t sql_errno  __attribute__((unused)),
1663
1626
             const char *message,
1664
1627
             DRIZZLE_ERROR::enum_warning_level level __attribute__((unused)),
1665
 
             THD *thd __attribute__((unused)))
 
1628
             Session *session __attribute__((unused)))
1666
1629
{
1667
1630
  /* Grab the error message */
1668
1631
  strmake(buff, message, sizeof(buff)-1);
1674
1637
  This should return ENOENT if the file doesn't exists.
1675
1638
  The .frm file will be deleted only if we return 0 or ENOENT
1676
1639
*/
1677
 
int ha_delete_table(THD *thd, handlerton *table_type, const char *path,
 
1640
int ha_delete_table(Session *session, handlerton *table_type, const char *path,
1678
1641
                    const char *db, const char *alias, bool generate_warning)
1679
1642
{
1680
1643
  handler *file;
1689
1652
 
1690
1653
  /* DB_TYPE_UNKNOWN is used in ALTER Table when renaming only .frm files */
1691
1654
  if (table_type == NULL ||
1692
 
      ! (file=get_new_handler((TABLE_SHARE*)0, thd->mem_root, table_type)))
 
1655
      ! (file=get_new_handler((TABLE_SHARE*)0, session->mem_root, table_type)))
1693
1656
    return(ENOENT);
1694
1657
 
1695
1658
  path= check_lowercase_names(file, path, tmp_path);
1714
1677
 
1715
1678
    file->change_table_ptr(&dummy_table, &dummy_share);
1716
1679
 
1717
 
    thd->push_internal_handler(&ha_delete_table_error_handler);
 
1680
    session->push_internal_handler(&ha_delete_table_error_handler);
1718
1681
    file->print_error(error, 0);
1719
1682
 
1720
 
    thd->pop_internal_handler();
 
1683
    session->pop_internal_handler();
1721
1684
 
1722
1685
    /*
1723
1686
      XXX: should we convert *all* errors to warnings here?
1724
1687
      What if the error is fatal?
1725
1688
    */
1726
 
    push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_ERROR, error,
 
1689
    push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_ERROR, error,
1727
1690
                ha_delete_table_error_handler.buff);
1728
1691
  }
1729
1692
  delete file;
1758
1721
  status_var_increment(table->in_use->status_var.*offset);
1759
1722
}
1760
1723
 
1761
 
void **handler::ha_data(THD *thd) const
 
1724
void **handler::ha_data(Session *session) const
1762
1725
{
1763
 
  return thd_ha_data(thd, ht);
 
1726
  return session_ha_data(session, ht);
1764
1727
}
1765
1728
 
1766
 
THD *handler::ha_thd(void) const
 
1729
Session *handler::ha_session(void) const
1767
1730
{
1768
 
  assert(!table || !table->in_use || table->in_use == current_thd);
1769
 
  return (table && table->in_use) ? table->in_use : current_thd;
 
1731
  assert(!table || !table->in_use || table->in_use == current_session);
 
1732
  return (table && table->in_use) ? table->in_use : current_session;
1770
1733
}
1771
1734
 
1772
1735
/**
1898
1861
void handler::adjust_next_insert_id_after_explicit_value(uint64_t nr)
1899
1862
{
1900
1863
  /*
1901
 
    If we have set THD::next_insert_id previously and plan to insert an
 
1864
    If we have set Session::next_insert_id previously and plan to insert an
1902
1865
    explicitely-specified value larger than this, we need to increase
1903
 
    THD::next_insert_id to be greater than the explicit value.
 
1866
    Session::next_insert_id to be greater than the explicit value.
1904
1867
  */
1905
1868
  if ((next_insert_id > 0) && (nr >= next_insert_id))
1906
1869
    set_next_insert_id(compute_next_insert_id(nr, &table->in_use->variables));
1976
1939
    again to reserve a new interval.
1977
1940
 
1978
1941
  - In both cases, the reserved intervals are remembered in
1979
 
    thd->auto_inc_intervals_in_cur_stmt_for_binlog if statement-based
 
1942
    session->auto_inc_intervals_in_cur_stmt_for_binlog if statement-based
1980
1943
    binlogging; the last reserved interval is remembered in
1981
1944
    auto_inc_interval_for_cur_row.
1982
1945
 
1990
1953
    start counting from the inserted value.
1991
1954
 
1992
1955
    This function's "outputs" are: the table's auto_increment field is filled
1993
 
    with a value, thd->next_insert_id is filled with the value to use for the
 
1956
    with a value, session->next_insert_id is filled with the value to use for the
1994
1957
    next row, if a value was autogenerated for the current row it is stored in
1995
 
    thd->insert_id_for_cur_row, if get_auto_increment() was called
1996
 
    thd->auto_inc_interval_for_cur_row is modified, if that interval is not
1997
 
    present in thd->auto_inc_intervals_in_cur_stmt_for_binlog it is added to
 
1958
    session->insert_id_for_cur_row, if get_auto_increment() was called
 
1959
    session->auto_inc_interval_for_cur_row is modified, if that interval is not
 
1960
    present in session->auto_inc_intervals_in_cur_stmt_for_binlog it is added to
1998
1961
    this list.
1999
1962
 
2000
1963
  @todo
2021
1984
{
2022
1985
  uint64_t nr, nb_reserved_values;
2023
1986
  bool append= false;
2024
 
  THD *thd= table->in_use;
2025
 
  struct system_variables *variables= &thd->variables;
 
1987
  Session *session= table->in_use;
 
1988
  struct system_variables *variables= &session->variables;
2026
1989
 
2027
1990
  /*
2028
1991
    next_insert_id is a "cursor" into the reserved interval, it may go greater
2047
2010
  {
2048
2011
    /* next_insert_id is beyond what is reserved, so we reserve more. */
2049
2012
    const Discrete_interval *forced=
2050
 
      thd->auto_inc_intervals_forced.get_next();
 
2013
      session->auto_inc_intervals_forced.get_next();
2051
2014
    if (forced != NULL)
2052
2015
    {
2053
2016
      nr= forced->minimum();
2060
2023
        handler::ha_start_bulk_insert(); if 0 it means "unknown".
2061
2024
      */
2062
2025
      uint32_t nb_already_reserved_intervals=
2063
 
        thd->auto_inc_intervals_in_cur_stmt_for_binlog.nb_elements();
 
2026
        session->auto_inc_intervals_in_cur_stmt_for_binlog.nb_elements();
2064
2027
      uint64_t nb_desired_values;
2065
2028
      /*
2066
2029
        If an estimation was given to the engine:
2119
2082
    /*
2120
2083
      first test if the query was aborted due to strict mode constraints
2121
2084
    */
2122
 
    if (thd->killed == THD::KILL_BAD_DATA)
 
2085
    if (session->killed == Session::KILL_BAD_DATA)
2123
2086
      return(HA_ERR_AUTOINC_ERANGE);
2124
2087
 
2125
2088
    /*
2139
2102
    auto_inc_interval_for_cur_row.replace(nr, nb_reserved_values,
2140
2103
                                          variables->auto_increment_increment);
2141
2104
    /* Row-based replication does not need to store intervals in binlog */
2142
 
    if (!thd->current_stmt_binlog_row_based)
2143
 
        thd->auto_inc_intervals_in_cur_stmt_for_binlog.append(auto_inc_interval_for_cur_row.minimum(),
 
2105
    if (!session->current_stmt_binlog_row_based)
 
2106
        session->auto_inc_intervals_in_cur_stmt_for_binlog.append(auto_inc_interval_for_cur_row.minimum(),
2144
2107
                                                              auto_inc_interval_for_cur_row.values(),
2145
2108
                                                              variables->auto_increment_increment);
2146
2109
  }
2559
2522
 
2560
2523
  strxmov(path, table->s->normalized_path.str, reg_ext, NULL);
2561
2524
 
2562
 
  if ((file= my_open(path, O_RDWR|O_BINARY, MYF(MY_WME))) >= 0)
 
2525
  if ((file= my_open(path, O_RDWR, MYF(MY_WME))) >= 0)
2563
2526
  {
2564
2527
    unsigned char version[4];
2565
2528
    char *key= table->s->table_cache_key.str;
2666
2629
/**
2667
2630
  Performs checks upon the table.
2668
2631
 
2669
 
  @param thd                thread doing CHECK Table operation
 
2632
  @param session                thread doing CHECK Table operation
2670
2633
  @param check_opt          options from the parser
2671
2634
 
2672
2635
  @retval
2678
2641
  @retval
2679
2642
    HA_ADMIN_NOT_IMPLEMENTED
2680
2643
*/
2681
 
int handler::ha_check(THD *thd, HA_CHECK_OPT *check_opt)
 
2644
int handler::ha_check(Session *session, HA_CHECK_OPT *check_opt)
2682
2645
{
2683
2646
  int error;
2684
2647
 
2696
2659
    if (!error && (check_opt->sql_flags & TT_FOR_UPGRADE))
2697
2660
      return 0;
2698
2661
  }
2699
 
  if ((error= check(thd, check_opt)))
 
2662
  if ((error= check(session, check_opt)))
2700
2663
    return error;
2701
2664
  return update_frm_version(table);
2702
2665
}
2710
2673
void
2711
2674
handler::mark_trx_read_write()
2712
2675
{
2713
 
  Ha_trx_info *ha_info= &ha_thd()->ha_data[ht->slot].ha_info[0];
 
2676
  Ha_trx_info *ha_info= &ha_session()->ha_data[ht->slot].ha_info[0];
2714
2677
  /*
2715
2678
    When a storage engine method is called, the transaction must
2716
2679
    have been started, unless it's a DDL call, for which the
2738
2701
  @sa handler::repair()
2739
2702
*/
2740
2703
 
2741
 
int handler::ha_repair(THD* thd, HA_CHECK_OPT* check_opt)
 
2704
int handler::ha_repair(Session* session, HA_CHECK_OPT* check_opt)
2742
2705
{
2743
2706
  int result;
2744
2707
 
2745
2708
  mark_trx_read_write();
2746
2709
 
2747
 
  if ((result= repair(thd, check_opt)))
 
2710
  if ((result= repair(session, check_opt)))
2748
2711
    return result;
2749
2712
  return update_frm_version(table);
2750
2713
}
2803
2766
*/
2804
2767
 
2805
2768
int
2806
 
handler::ha_optimize(THD* thd, HA_CHECK_OPT* check_opt)
 
2769
handler::ha_optimize(Session* session, HA_CHECK_OPT* check_opt)
2807
2770
{
2808
2771
  mark_trx_read_write();
2809
2772
 
2810
 
  return optimize(thd, check_opt);
 
2773
  return optimize(session, check_opt);
2811
2774
}
2812
2775
 
2813
2776
 
2818
2781
*/
2819
2782
 
2820
2783
int
2821
 
handler::ha_analyze(THD* thd, HA_CHECK_OPT* check_opt)
 
2784
handler::ha_analyze(Session* session, HA_CHECK_OPT* check_opt)
2822
2785
{
2823
2786
  mark_trx_read_write();
2824
2787
 
2825
 
  return analyze(thd, check_opt);
 
2788
  return analyze(session, check_opt);
2826
2789
}
2827
2790
 
2828
2791
 
2833
2796
*/
2834
2797
 
2835
2798
bool
2836
 
handler::ha_check_and_repair(THD *thd)
 
2799
handler::ha_check_and_repair(Session *session)
2837
2800
{
2838
2801
  mark_trx_read_write();
2839
2802
 
2840
 
  return check_and_repair(thd);
 
2803
  return check_and_repair(session);
2841
2804
}
2842
2805
 
2843
2806
 
2987
2950
  starts to commit every now and then automatically.
2988
2951
  This hint can be safely ignored.
2989
2952
*/
2990
 
int ha_enable_transaction(THD *thd, bool on)
 
2953
int ha_enable_transaction(Session *session, bool on)
2991
2954
{
2992
2955
  int error=0;
2993
2956
 
2994
 
  if ((thd->transaction.on= on))
 
2957
  if ((session->transaction.on= on))
2995
2958
  {
2996
2959
    /*
2997
2960
      Now all storage engines should have transaction handling enabled.
2999
2962
      is an optimization hint that storage engine is free to ignore.
3000
2963
      So, let's commit an open transaction (if any) now.
3001
2964
    */
3002
 
    if (!(error= ha_commit_trans(thd, 0)))
3003
 
      error= end_trans(thd, COMMIT);
 
2965
    if (!(error= ha_commit_trans(session, 0)))
 
2966
      error= end_trans(session, COMMIT);
3004
2967
  }
3005
2968
  return(error);
3006
2969
}
3068
3031
  @retval
3069
3032
   1  error
3070
3033
*/
3071
 
int ha_create_table(THD *thd, const char *path,
 
3034
int ha_create_table(Session *session, const char *path,
3072
3035
                    const char *db, const char *table_name,
3073
3036
                    HA_CREATE_INFO *create_info,
3074
3037
                    bool update_create_info)
3079
3042
  const char *name;
3080
3043
  TABLE_SHARE share;
3081
3044
  
3082
 
  init_tmp_table_share(thd, &share, db, 0, table_name, path);
3083
 
  if (open_table_def(thd, &share, 0) ||
3084
 
      open_table_from_share(thd, &share, "", 0, (uint) READ_ALL, 0, &table,
 
3045
  init_tmp_table_share(session, &share, db, 0, table_name, path);
 
3046
  if (open_table_def(session, &share, 0) ||
 
3047
      open_table_from_share(session, &share, "", 0, (uint) READ_ALL, 0, &table,
3085
3048
                            OTM_CREATE))
3086
3049
    goto err;
3087
3050
 
3115
3078
  @retval
3116
3079
   > 0  Error, table existed but could not be created
3117
3080
*/
3118
 
int ha_create_table_from_engine(THD* thd, const char *db, const char *name)
 
3081
int ha_create_table_from_engine(Session* session, const char *db, const char *name)
3119
3082
{
3120
3083
  int error;
3121
3084
  unsigned char *frmblob;
3126
3089
  TABLE_SHARE share;
3127
3090
 
3128
3091
  memset(&create_info, 0, sizeof(create_info));
3129
 
  if ((error= ha_discover(thd, db, name, &frmblob, &frmlen)))
 
3092
  if ((error= ha_discover(session, db, name, &frmblob, &frmlen)))
3130
3093
  {
3131
3094
    /* Table could not be discovered and thus not created */
3132
3095
    return(error);
3144
3107
  if (error)
3145
3108
    return(2);
3146
3109
 
3147
 
  init_tmp_table_share(thd, &share, db, 0, name, path);
3148
 
  if (open_table_def(thd, &share, 0))
 
3110
  init_tmp_table_share(session, &share, db, 0, name, path);
 
3111
  if (open_table_def(session, &share, 0))
3149
3112
  {
3150
3113
    return(3);
3151
3114
  }
3152
 
  if (open_table_from_share(thd, &share, "" ,0, 0, 0, &table, OTM_OPEN))
 
3115
  if (open_table_from_share(session, &share, "" ,0, 0, 0, &table, OTM_OPEN))
3153
3116
  {
3154
3117
    free_table_share(&share);
3155
3118
    return(3);
3168
3131
void st_ha_check_opt::init()
3169
3132
{
3170
3133
  flags= sql_flags= 0;
3171
 
  sort_buffer_size = current_thd->variables.myisam_sort_buff_size;
 
3134
  sort_buffer_size = current_session->variables.myisam_sort_buff_size;
3172
3135
}
3173
3136
 
3174
3137
 
3280
3243
  size_t *frmlen;
3281
3244
};
3282
3245
 
3283
 
static bool discover_handlerton(THD *thd, plugin_ref plugin,
 
3246
static bool discover_handlerton(Session *session, plugin_ref plugin,
3284
3247
                                void *arg)
3285
3248
{
3286
3249
  st_discover_args *vargs= (st_discover_args *)arg;
3287
3250
  handlerton *hton= plugin_data(plugin, handlerton *);
3288
3251
  if (hton->state == SHOW_OPTION_YES && hton->discover &&
3289
 
      (!(hton->discover(hton, thd, vargs->db, vargs->name, 
 
3252
      (!(hton->discover(hton, session, vargs->db, vargs->name, 
3290
3253
                        vargs->frmblob, 
3291
3254
                        vargs->frmlen))))
3292
3255
    return true;
3294
3257
  return false;
3295
3258
}
3296
3259
 
3297
 
int ha_discover(THD *thd, const char *db, const char *name,
 
3260
int ha_discover(Session *session, const char *db, const char *name,
3298
3261
                unsigned char **frmblob, size_t *frmlen)
3299
3262
{
3300
3263
  int error= -1; // Table does not exist in any handler
3303
3266
  if (is_prefix(name,tmp_file_prefix)) /* skip temporary tables */
3304
3267
    return(error);
3305
3268
 
3306
 
  if (plugin_foreach(thd, discover_handlerton,
 
3269
  if (plugin_foreach(session, discover_handlerton,
3307
3270
                 DRIZZLE_STORAGE_ENGINE_PLUGIN, &args))
3308
3271
    error= 0;
3309
3272
 
3310
3273
  if (!error)
3311
 
    status_var_increment(thd->status_var.ha_discover_count);
 
3274
    status_var_increment(session->status_var.ha_discover_count);
3312
3275
  return(error);
3313
3276
}
3314
3277
 
3343
3306
  int err;
3344
3307
};
3345
3308
 
3346
 
static bool table_exists_in_engine_handlerton(THD *thd, plugin_ref plugin,
 
3309
static bool table_exists_in_engine_handlerton(Session *session, plugin_ref plugin,
3347
3310
                                              void *arg)
3348
3311
{
3349
3312
  st_table_exists_in_engine_args *vargs= (st_table_exists_in_engine_args *)arg;
3352
3315
  int err= HA_ERR_NO_SUCH_TABLE;
3353
3316
 
3354
3317
  if (hton->state == SHOW_OPTION_YES && hton->table_exists_in_engine)
3355
 
    err = hton->table_exists_in_engine(hton, thd, vargs->db, vargs->name);
 
3318
    err = hton->table_exists_in_engine(hton, session, vargs->db, vargs->name);
3356
3319
 
3357
3320
  vargs->err = err;
3358
3321
  if (vargs->err == HA_ERR_TABLE_EXIST)
3361
3324
  return false;
3362
3325
}
3363
3326
 
3364
 
int ha_table_exists_in_engine(THD* thd, const char* db, const char* name)
 
3327
int ha_table_exists_in_engine(Session* session, const char* db, const char* name)
3365
3328
{
3366
3329
  st_table_exists_in_engine_args args= {db, name, HA_ERR_NO_SUCH_TABLE};
3367
 
  plugin_foreach(thd, table_exists_in_engine_handlerton,
 
3330
  plugin_foreach(session, table_exists_in_engine_handlerton,
3368
3331
                 DRIZZLE_STORAGE_ENGINE_PLUGIN, &args);
3369
3332
  return(args.err);
3370
3333
}
3424
3387
 
3425
3388
  @note
3426
3389
    This method (or an overriding one in a derived class) must check for
3427
 
    thd->killed and return HA_POS_ERROR if it is not zero. This is required
 
3390
    session->killed and return HA_POS_ERROR if it is not zero. This is required
3428
3391
    for a user to be able to interrupt the calculation by killing the
3429
3392
    connection/query.
3430
3393
 
3446
3409
  range_seq_t seq_it;
3447
3410
  ha_rows rows, total_rows= 0;
3448
3411
  uint32_t n_ranges=0;
3449
 
  THD *thd= current_thd;
 
3412
  Session *session= current_session;
3450
3413
  
3451
3414
  /* Default MRR implementation doesn't need buffer */
3452
3415
  *bufsz= 0;
3454
3417
  seq_it= seq->init(seq_init_param, n_ranges, *flags);
3455
3418
  while (!seq->next(seq_it, &range))
3456
3419
  {
3457
 
    if (unlikely(thd->killed != 0))
 
3420
    if (unlikely(session->killed != 0))
3458
3421
      return HA_POS_ERROR;
3459
3422
    
3460
3423
    n_ranges++;
3720
3683
  rowids_buf_end= rowids_buf_last;
3721
3684
 
3722
3685
  /* Create a separate handler object to do rndpos() calls. */
3723
 
  THD *thd= current_thd;
3724
 
  if (!(new_h2= h->clone(thd->mem_root)) || 
3725
 
      new_h2->ha_external_lock(thd, F_RDLCK))
 
3686
  Session *session= current_session;
 
3687
  if (!(new_h2= h->clone(session->mem_root)) || 
 
3688
      new_h2->ha_external_lock(session, F_RDLCK))
3726
3689
  {
3727
3690
    delete new_h2;
3728
3691
    return(1);
3764
3727
  return(0);
3765
3728
error:
3766
3729
  h2->ha_index_or_rnd_end();
3767
 
  h2->ha_external_lock(thd, F_UNLCK);
 
3730
  h2->ha_external_lock(session, F_UNLCK);
3768
3731
  h2->close();
3769
3732
  delete h2;
3770
3733
  return(1);
3775
3738
{
3776
3739
  if (h2)
3777
3740
  {
3778
 
    h2->ha_external_lock(current_thd, F_UNLCK);
 
3741
    h2->ha_external_lock(current_session, F_UNLCK);
3779
3742
    h2->close();
3780
3743
    delete h2;
3781
3744
    h2= NULL;
4015
3978
{
4016
3979
  COST_VECT dsmrr_cost;
4017
3980
  bool res;
4018
 
  THD *thd= current_thd;
4019
 
  if ((thd->variables.optimizer_use_mrr == 2) || 
 
3981
  Session *session= current_session;
 
3982
  if ((session->variables.optimizer_use_mrr == 2) || 
4020
3983
      (*flags & HA_MRR_INDEX_ONLY) || (*flags & HA_MRR_SORTED) ||
4021
3984
      (keyno == table->s->primary_key && 
4022
3985
       h->primary_key_is_clustered()) || 
4040
4003
    DS-MRR whenever it is applicable without affecting other cost-based
4041
4004
    choices.
4042
4005
  */
4043
 
  if ((force_dsmrr= (thd->variables.optimizer_use_mrr == 1)) &&
 
4006
  if ((force_dsmrr= (session->variables.optimizer_use_mrr == 1)) &&
4044
4007
      dsmrr_cost.total_cost() > cost->total_cost())
4045
4008
    dsmrr_cost= *cost;
4046
4009
 
4393
4356
  @retval
4394
4357
    pointer             pointer to TYPELIB structure
4395
4358
*/
4396
 
static bool exts_handlerton(THD *unused __attribute__((unused)),
 
4359
static bool exts_handlerton(Session *unused __attribute__((unused)),
4397
4360
                            plugin_ref plugin,
4398
4361
                            void *arg)
4399
4362
{
4401
4364
  handlerton *hton= plugin_data(plugin, handlerton *);
4402
4365
  handler *file;
4403
4366
  if (hton->state == SHOW_OPTION_YES && hton->create &&
4404
 
      (file= hton->create(hton, (TABLE_SHARE*) 0, current_thd->mem_root)))
 
4367
      (file= hton->create(hton, (TABLE_SHARE*) 0, current_session->mem_root)))
4405
4368
  {
4406
4369
    List_iterator_fast<char> it(*found_exts);
4407
4370
    const char **ext, *old_ext;
4452
4415
}
4453
4416
 
4454
4417
 
4455
 
static bool stat_print(THD *thd, const char *type, uint32_t type_len,
 
4418
static bool stat_print(Session *session, const char *type, uint32_t type_len,
4456
4419
                       const char *file, uint32_t file_len,
4457
4420
                       const char *status, uint32_t status_len)
4458
4421
{
4459
 
  Protocol *protocol= thd->protocol;
 
4422
  Protocol *protocol= session->protocol;
4460
4423
  protocol->prepare_for_resend();
4461
4424
  protocol->store(type, type_len, system_charset_info);
4462
4425
  protocol->store(file, file_len, system_charset_info);
4466
4429
  return false;
4467
4430
}
4468
4431
 
4469
 
bool ha_show_status(THD *thd, handlerton *db_type, enum ha_stat_type stat)
 
4432
bool ha_show_status(Session *session, handlerton *db_type, enum ha_stat_type stat)
4470
4433
{
4471
4434
  List<Item> field_list;
4472
 
  Protocol *protocol= thd->protocol;
 
4435
  Protocol *protocol= session->protocol;
4473
4436
  bool result;
4474
4437
 
4475
4438
  field_list.push_back(new Item_empty_string("Type",10));
4481
4444
    return true;
4482
4445
 
4483
4446
  result= db_type->show_status &&
4484
 
    db_type->show_status(db_type, thd, stat_print, stat) ? 1 : 0;
 
4447
    db_type->show_status(db_type, session, stat_print, stat) ? 1 : 0;
4485
4448
 
4486
4449
  if (!result)
4487
 
    my_eof(thd);
 
4450
    my_eof(session);
4488
4451
  return result;
4489
4452
}
4490
4453
 
4501
4464
  - table is not mysql.event
4502
4465
*/
4503
4466
 
4504
 
static bool check_table_binlog_row_based(THD *thd, Table *table)
 
4467
static bool check_table_binlog_row_based(Session *session, Table *table)
4505
4468
{
4506
4469
  if (table->s->cached_row_logging_check == -1)
4507
4470
  {
4513
4476
  assert(table->s->cached_row_logging_check == 0 ||
4514
4477
              table->s->cached_row_logging_check == 1);
4515
4478
 
4516
 
  return (thd->current_stmt_binlog_row_based &&
 
4479
  return (session->current_stmt_binlog_row_based &&
4517
4480
          table->s->cached_row_logging_check &&
4518
 
          (thd->options & OPTION_BIN_LOG) &&
 
4481
          (session->options & OPTION_BIN_LOG) &&
4519
4482
          mysql_bin_log.is_open());
4520
4483
}
4521
4484
 
4525
4488
   to the binary log.
4526
4489
 
4527
4490
   This function will generate and write table maps for all tables
4528
 
   that are locked by the thread 'thd'.  Either manually locked
4529
 
   (stored in THD::locked_tables) and automatically locked (stored
4530
 
   in THD::lock) are considered.
 
4491
   that are locked by the thread 'session'.  Either manually locked
 
4492
   (stored in Session::locked_tables) and automatically locked (stored
 
4493
   in Session::lock) are considered.
4531
4494
 
4532
 
   @param thd     Pointer to THD structure
 
4495
   @param session     Pointer to Session structure
4533
4496
 
4534
4497
   @retval 0   All OK
4535
4498
   @retval 1   Failed to write all table maps
4536
4499
 
4537
4500
   @sa
4538
 
       THD::lock
4539
 
       THD::locked_tables
 
4501
       Session::lock
 
4502
       Session::locked_tables
4540
4503
*/
4541
4504
 
4542
 
static int write_locked_table_maps(THD *thd)
 
4505
static int write_locked_table_maps(Session *session)
4543
4506
{
4544
 
  if (thd->get_binlog_table_maps() == 0)
 
4507
  if (session->get_binlog_table_maps() == 0)
4545
4508
  {
4546
4509
    DRIZZLE_LOCK *locks[3];
4547
 
    locks[0]= thd->extra_lock;
4548
 
    locks[1]= thd->lock;
4549
 
    locks[2]= thd->locked_tables;
 
4510
    locks[0]= session->extra_lock;
 
4511
    locks[1]= session->lock;
 
4512
    locks[2]= session->locked_tables;
4550
4513
    for (uint32_t i= 0 ; i < sizeof(locks)/sizeof(*locks) ; ++i )
4551
4514
    {
4552
4515
      DRIZZLE_LOCK const *const lock= locks[i];
4560
4523
      {
4561
4524
        Table *const table= *table_ptr;
4562
4525
        if (table->current_lock == F_WRLCK &&
4563
 
            check_table_binlog_row_based(thd, table))
 
4526
            check_table_binlog_row_based(session, table))
4564
4527
        {
4565
4528
          int const has_trans= table->file->has_transactions();
4566
 
          int const error= thd->binlog_write_table_map(table, has_trans);
 
4529
          int const error= session->binlog_write_table_map(table, has_trans);
4567
4530
          /*
4568
4531
            If an error occurs, it is the responsibility of the caller to
4569
4532
            roll back the transaction.
4578
4541
}
4579
4542
 
4580
4543
 
4581
 
typedef bool Log_func(THD*, Table*, bool, const unsigned char*, const unsigned char*);
 
4544
typedef bool Log_func(Session*, Table*, bool, const unsigned char*, const unsigned char*);
4582
4545
 
4583
4546
static int binlog_log_row(Table* table,
4584
4547
                          const unsigned char *before_record,
4588
4551
  if (table->no_replicate)
4589
4552
    return 0;
4590
4553
  bool error= 0;
4591
 
  THD *const thd= table->in_use;
 
4554
  Session *const session= table->in_use;
4592
4555
 
4593
 
  if (check_table_binlog_row_based(thd, table))
 
4556
  if (check_table_binlog_row_based(session, table))
4594
4557
  {
4595
4558
    /*
4596
4559
      If there are no table maps written to the binary log, this is
4597
4560
      the first row handled in this statement. In that case, we need
4598
4561
      to write table maps for all locked tables to the binary log.
4599
4562
    */
4600
 
    if (likely(!(error= write_locked_table_maps(thd))))
 
4563
    if (likely(!(error= write_locked_table_maps(session))))
4601
4564
    {
4602
4565
      bool const has_trans= table->file->has_transactions();
4603
 
      error= (*log_func)(thd, table, has_trans, before_record, after_record);
 
4566
      error= (*log_func)(session, table, has_trans, before_record, after_record);
4604
4567
    }
4605
4568
  }
4606
4569
  return error ? HA_ERR_RBR_LOGGING_FAILED : 0;
4607
4570
}
4608
4571
 
4609
 
int handler::ha_external_lock(THD *thd, int lock_type)
 
4572
int handler::ha_external_lock(Session *session, int lock_type)
4610
4573
{
4611
4574
  /*
4612
4575
    Whether this is lock or unlock, this should be true, and is to verify that
4621
4584
  */
4622
4585
  DRIZZLE_EXTERNAL_LOCK(lock_type);
4623
4586
 
4624
 
  int error= external_lock(thd, lock_type);
 
4587
  int error= external_lock(session, lock_type);
4625
4588
  if (error == 0)
4626
4589
    cached_table_flags= table_flags();
4627
4590
  return(error);
4713
4676
  /* fallback to use all columns in the table to identify row */
4714
4677
  table->use_all_columns();
4715
4678
}
 
4679
 
 
4680
void table_case_convert(char * name, uint32_t length)
 
4681
{
 
4682
  if (lower_case_table_names)
 
4683
    files_charset_info->cset->casedn(files_charset_info,
 
4684
                                     name, length, name, length);
 
4685
}
 
4686
 
 
4687
const char *table_case_name(HA_CREATE_INFO *info, const char *name)
 
4688
{
 
4689
  return ((lower_case_table_names == 2 && info->alias) ? info->alias : name);
 
4690
}