~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/handler.cc

  • Committer: Monty Taylor
  • Date: 2008-10-23 23:53:49 UTC
  • mto: This revision was merged to the branch mainline in revision 557.
  • Revision ID: monty@inaugust.com-20081023235349-317wgwqwgccuacmq
SplitĀ outĀ nested_join.h.

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