~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/handler.cc

  • Committer: Monty Taylor
  • Date: 2008-10-02 01:27:37 UTC
  • Revision ID: monty@inaugust.com-20081002012737-3uxmdovii2l14uqe
Removed unused crud.

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
 
22
26
#include <drizzled/server_includes.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
 
#include CMATH_H
30
 
 
31
 
#if defined(CMATH_NAMESPACE)
32
 
using namespace CMATH_NAMESPACE;
33
 
#endif
 
27
#include "rpl_filter.h"
 
28
#include <drizzled/drizzled_error_messages.h>
34
29
 
35
30
/*
36
31
  While we have legacy_db_type, we have this array to
41
36
 
42
37
static handlerton *installed_htons[128];
43
38
 
44
 
KEY_CREATE_INFO default_key_create_info= { HA_KEY_ALG_UNDEF, 0, {NULL,0}, {NULL,0} };
 
39
#define BITMAP_STACKBUF_SIZE (128/8)
 
40
 
 
41
KEY_CREATE_INFO default_key_create_info= { HA_KEY_ALG_UNDEF, 0, {NullS,0}, {NullS,0} };
45
42
 
46
43
/* number of entries in handlertons[] */
47
44
uint32_t total_ha= 0;
54
51
{
55
52
  { C_STRING_WITH_LEN("INNOBASE") },  { C_STRING_WITH_LEN("INNODB") },
56
53
  { C_STRING_WITH_LEN("HEAP") },      { C_STRING_WITH_LEN("MEMORY") },
57
 
  {NULL, 0}
 
54
  {NullS, 0}
58
55
};
59
56
 
60
57
const char *ha_row_type[] = {
63
60
 
64
61
const char *tx_isolation_names[] =
65
62
{ "READ-UNCOMMITTED", "READ-COMMITTED", "REPEATABLE-READ", "SERIALIZABLE",
66
 
  NULL};
 
63
  NullS};
67
64
TYPELIB tx_isolation_typelib= {array_elements(tx_isolation_names)-1,"",
68
65
                               tx_isolation_names, NULL};
69
66
 
70
67
static TYPELIB known_extensions= {0,"known_exts", NULL, NULL};
71
 
uint32_t known_extensions_id= 0;
72
 
 
73
 
 
74
 
 
75
 
static plugin_ref ha_default_plugin(Session *session)
 
68
uint known_extensions_id= 0;
 
69
 
 
70
 
 
71
 
 
72
static plugin_ref ha_default_plugin(THD *thd)
76
73
{
77
 
  if (session->variables.table_plugin)
78
 
    return session->variables.table_plugin;
79
 
  return my_plugin_lock(session, &global_system_variables.table_plugin);
 
74
  if (thd->variables.table_plugin)
 
75
    return thd->variables.table_plugin;
 
76
  return my_plugin_lock(thd, &global_system_variables.table_plugin);
80
77
}
81
78
 
82
79
 
83
80
/**
84
81
  Return the default storage engine handlerton for thread
85
82
 
86
 
  @param ha_default_handlerton(session)
87
 
  @param session         current thread
 
83
  @param ha_default_handlerton(thd)
 
84
  @param thd         current thread
88
85
 
89
86
  @return
90
87
    pointer to handlerton
91
88
*/
92
 
handlerton *ha_default_handlerton(Session *session)
 
89
handlerton *ha_default_handlerton(THD *thd)
93
90
{
94
 
  plugin_ref plugin= ha_default_plugin(session);
 
91
  plugin_ref plugin= ha_default_plugin(thd);
95
92
  assert(plugin);
96
93
  handlerton *hton= plugin_data(plugin, handlerton*);
97
94
  assert(hton);
102
99
/**
103
100
  Return the storage engine handlerton for the supplied name
104
101
  
105
 
  @param session         current thread
 
102
  @param thd         current thread
106
103
  @param name        name of storage engine
107
104
  
108
105
  @return
109
106
    pointer to storage engine plugin handle
110
107
*/
111
 
plugin_ref ha_resolve_by_name(Session *session, const LEX_STRING *name)
 
108
plugin_ref ha_resolve_by_name(THD *thd, const LEX_STRING *name)
112
109
{
113
110
  const LEX_STRING *table_alias;
114
111
  plugin_ref plugin;
115
112
 
116
113
redo:
117
114
  /* my_strnncoll is a macro and gcc doesn't do early expansion of macro */
118
 
  if (session && !my_charset_utf8_general_ci.coll->strnncoll(&my_charset_utf8_general_ci,
119
 
                           (const unsigned char *)name->str, name->length,
120
 
                           (const unsigned char *)STRING_WITH_LEN("DEFAULT"), 0))
121
 
    return ha_default_plugin(session);
 
115
  if (thd && !my_charset_utf8_general_ci.coll->strnncoll(&my_charset_utf8_general_ci,
 
116
                           (const uchar *)name->str, name->length,
 
117
                           (const uchar *)STRING_WITH_LEN("DEFAULT"), 0))
 
118
    return ha_default_plugin(thd);
122
119
 
123
 
  if ((plugin= my_plugin_lock_by_name(session, name, DRIZZLE_STORAGE_ENGINE_PLUGIN)))
 
120
  if ((plugin= my_plugin_lock_by_name(thd, name, DRIZZLE_STORAGE_ENGINE_PLUGIN)))
124
121
  {
125
122
    handlerton *hton= plugin_data(plugin, handlerton *);
126
123
    if (!(hton->flags & HTON_NOT_USER_SELECTABLE))
129
126
    /*
130
127
      unlocking plugin immediately after locking is relatively low cost.
131
128
    */
132
 
    plugin_unlock(session, plugin);
 
129
    plugin_unlock(thd, plugin);
133
130
  }
134
131
 
135
132
  /*
138
135
  for (table_alias= sys_table_aliases; table_alias->str; table_alias+= 2)
139
136
  {
140
137
    if (!my_strnncoll(&my_charset_utf8_general_ci,
141
 
                      (const unsigned char *)name->str, name->length,
142
 
                      (const unsigned char *)table_alias->str, table_alias->length))
 
138
                      (const uchar *)name->str, name->length,
 
139
                      (const uchar *)table_alias->str, table_alias->length))
143
140
    {
144
141
      name= table_alias + 1;
145
142
      goto redo;
150
147
}
151
148
 
152
149
 
153
 
plugin_ref ha_lock_engine(Session *session, handlerton *hton)
 
150
plugin_ref ha_lock_engine(THD *thd, handlerton *hton)
154
151
{
155
152
  if (hton)
156
153
  {
157
154
    st_plugin_int **plugin= hton2plugin + hton->slot;
158
155
    
159
 
    return my_plugin_lock(session, &plugin);
 
156
    return my_plugin_lock(thd, &plugin);
160
157
  }
161
158
  return NULL;
162
159
}
163
160
 
164
161
 
165
 
handlerton *ha_resolve_by_legacy_type(Session *session, enum legacy_db_type db_type)
 
162
handlerton *ha_resolve_by_legacy_type(THD *thd, enum legacy_db_type db_type)
166
163
{
167
164
  plugin_ref plugin;
168
165
  switch (db_type) {
169
166
  case DB_TYPE_DEFAULT:
170
 
    return ha_default_handlerton(session);
 
167
    return ha_default_handlerton(thd);
171
168
  default:
172
169
    if (db_type > DB_TYPE_UNKNOWN && db_type < DB_TYPE_DEFAULT &&
173
 
        (plugin= ha_lock_engine(session, installed_htons[db_type])))
 
170
        (plugin= ha_lock_engine(thd, installed_htons[db_type])))
174
171
      return plugin_data(plugin, handlerton*);
175
172
    /* fall through */
176
173
  case DB_TYPE_UNKNOWN:
182
179
/**
183
180
  Use other database handler if databasehandler is not compiled in.
184
181
*/
185
 
handlerton *ha_checktype(Session *session, enum legacy_db_type database_type,
 
182
handlerton *ha_checktype(THD *thd, enum legacy_db_type database_type,
186
183
                          bool no_substitute, bool report_error)
187
184
{
188
 
  handlerton *hton= ha_resolve_by_legacy_type(session, database_type);
 
185
  handlerton *hton= ha_resolve_by_legacy_type(thd, database_type);
189
186
  if (ha_storage_engine_is_enabled(hton))
190
187
    return hton;
191
188
 
199
196
    return NULL;
200
197
  }
201
198
 
202
 
  return ha_default_handlerton(session);
 
199
  return ha_default_handlerton(thd);
203
200
} /* ha_checktype */
204
201
 
205
202
 
216
213
  }
217
214
  /*
218
215
    Try the default table type
219
 
    Here the call to current_session() is ok as we call this function a lot of
 
216
    Here the call to current_thd() is ok as we call this function a lot of
220
217
    times but we enter this branch very seldom.
221
218
  */
222
 
  return(get_new_handler(share, alloc, ha_default_handlerton(current_session)));
 
219
  return(get_new_handler(share, alloc, ha_default_handlerton(current_thd)));
223
220
}
224
221
 
225
222
 
306
303
  /* Allocate a pointer array for the error message strings. */
307
304
  if (! (errmsgs= my_error_unregister(HA_ERR_FIRST, HA_ERR_LAST)))
308
305
    return 1;
309
 
  free((unsigned char*) errmsgs);
 
306
  my_free((uchar*) errmsgs, MYF(0));
310
307
  return 0;
311
308
}
312
309
 
329
326
  if (hton && plugin->plugin->deinit)
330
327
    (void)plugin->plugin->deinit(hton);
331
328
 
332
 
  free((unsigned char*)hton);
 
329
  my_free((uchar*)hton, MYF(0));
333
330
 
334
331
  return(0);
335
332
}
370
367
    break;
371
368
  case SHOW_OPTION_YES:
372
369
    {
373
 
      uint32_t tmp;
 
370
      uint tmp;
374
371
      /* now check the db_type for conflict */
375
372
      if (hton->db_type <= DB_TYPE_UNKNOWN ||
376
373
          hton->db_type >= DB_TYPE_DEFAULT ||
453
450
  return(error);
454
451
}
455
452
 
456
 
static bool dropdb_handlerton(Session *unused1 __attribute__((unused)),
 
453
static bool dropdb_handlerton(THD *unused1 __attribute__((unused)),
457
454
                              plugin_ref plugin,
458
455
                              void *path)
459
456
{
470
467
}
471
468
 
472
469
 
473
 
static bool closecon_handlerton(Session *session, plugin_ref plugin,
 
470
static bool closecon_handlerton(THD *thd, plugin_ref plugin,
474
471
                                void *unused __attribute__((unused)))
475
472
{
476
473
  handlerton *hton= plugin_data(plugin, handlerton *);
479
476
    be rolled back already
480
477
  */
481
478
  if (hton->state == SHOW_OPTION_YES && hton->close_connection &&
482
 
      session_get_ha_data(session, hton))
483
 
    hton->close_connection(hton, session);
 
479
      thd_get_ha_data(thd, hton))
 
480
    hton->close_connection(hton, thd);
484
481
  return false;
485
482
}
486
483
 
489
486
  @note
490
487
    don't bother to rollback here, it's done already
491
488
*/
492
 
void ha_close_connection(Session* session)
 
489
void ha_close_connection(THD* thd)
493
490
{
494
 
  plugin_foreach(session, closecon_handlerton, DRIZZLE_STORAGE_ENGINE_PLUGIN, 0);
 
491
  plugin_foreach(thd, closecon_handlerton, DRIZZLE_STORAGE_ENGINE_PLUGIN, 0);
495
492
}
496
493
 
497
494
/* ========================================================================
596
593
  -----------
597
594
 
598
595
  The server stores its transaction-related data in
599
 
  session->transaction. This structure has two members of type
600
 
  Session_TRANS. These members correspond to the statement and
 
596
  thd->transaction. This structure has two members of type
 
597
  THD_TRANS. These members correspond to the statement and
601
598
  normal transactions respectively:
602
599
 
603
 
  - session->transaction.stmt contains a list of engines
 
600
  - thd->transaction.stmt contains a list of engines
604
601
  that are participating in the given statement
605
 
  - session->transaction.all contains a list of engines that
 
602
  - thd->transaction.all contains a list of engines that
606
603
  have participated in any of the statement transactions started
607
604
  within the context of the normal transaction.
608
605
  Each element of the list contains a pointer to the storage
609
606
  engine, engine-specific transactional data, and engine-specific
610
607
  transaction flags.
611
608
 
612
 
  In autocommit mode session->transaction.all is empty.
613
 
  Instead, data of session->transaction.stmt is
 
609
  In autocommit mode thd->transaction.all is empty.
 
610
  Instead, data of thd->transaction.stmt is
614
611
  used to commit/rollback the normal transaction.
615
612
 
616
613
  The list of registered engines has a few important properties:
621
618
  Transaction life cycle
622
619
  ----------------------
623
620
 
624
 
  When a new connection is established, session->transaction
 
621
  When a new connection is established, thd->transaction
625
622
  members are initialized to an empty state.
626
623
  If a statement uses any tables, all affected engines
627
624
  are registered in the statement engine list. In
637
634
  and emptied again at the next statement's end.
638
635
 
639
636
  The normal transaction is committed in a similar way
640
 
  (by going over all engines in session->transaction.all list)
 
637
  (by going over all engines in thd->transaction.all list)
641
638
  but at different times:
642
639
  - upon COMMIT SQL statement is issued by the user
643
640
  - implicitly, by the server, at the beginning of a DDL statement
647
644
  - if the user has requested so, by issuing ROLLBACK SQL
648
645
  statement
649
646
  - if one of the storage engines requested a rollback
650
 
  by setting session->transaction_rollback_request. This may
 
647
  by setting thd->transaction_rollback_request. This may
651
648
  happen in case, e.g., when the transaction in the engine was
652
649
  chosen a victim of the internal deadlock resolution algorithm
653
650
  and rolled back internally. When such a situation happens, there
689
686
  transactions of other participants.
690
687
 
691
688
  After the normal transaction has been committed,
692
 
  session->transaction.all list is cleared.
 
689
  thd->transaction.all list is cleared.
693
690
 
694
691
  When a connection is closed, the current normal transaction, if
695
692
  any, is rolled back.
753
750
  ---------------------------------------------------
754
751
 
755
752
  DDLs and operations with non-transactional engines
756
 
  do not "register" in session->transaction lists, and thus do not
 
753
  do not "register" in thd->transaction lists, and thus do not
757
754
  modify the transaction state. Besides, each DDL in
758
755
  MySQL is prefixed with an implicit normal transaction commit
759
756
  (a call to end_active_trans()), and thus leaves nothing
800
797
    times per transaction.
801
798
 
802
799
*/
803
 
void trans_register_ha(Session *session, bool all, handlerton *ht_arg)
 
800
void trans_register_ha(THD *thd, bool all, handlerton *ht_arg)
804
801
{
805
 
  Session_TRANS *trans;
 
802
  THD_TRANS *trans;
806
803
  Ha_trx_info *ha_info;
807
804
 
808
805
  if (all)
809
806
  {
810
 
    trans= &session->transaction.all;
811
 
    session->server_status|= SERVER_STATUS_IN_TRANS;
 
807
    trans= &thd->transaction.all;
 
808
    thd->server_status|= SERVER_STATUS_IN_TRANS;
812
809
  }
813
810
  else
814
 
    trans= &session->transaction.stmt;
 
811
    trans= &thd->transaction.stmt;
815
812
 
816
 
  ha_info= session->ha_data[ht_arg->slot].ha_info + static_cast<unsigned>(all);
 
813
  ha_info= thd->ha_data[ht_arg->slot].ha_info + static_cast<unsigned>(all);
817
814
 
818
815
  if (ha_info->is_started())
819
816
    return; /* already registered, return */
821
818
  ha_info->register_ha(trans, ht_arg);
822
819
 
823
820
  trans->no_2pc|=(ht_arg->prepare==0);
824
 
  if (session->transaction.xid_state.xid.is_null())
825
 
    session->transaction.xid_state.xid.set(session->query_id);
 
821
  if (thd->transaction.xid_state.xid.is_null())
 
822
    thd->transaction.xid_state.xid.set(thd->query_id);
826
823
 
827
824
  return;
828
825
}
833
830
  @retval
834
831
    1   error, transaction was rolled back
835
832
*/
836
 
int ha_prepare(Session *session)
 
833
int ha_prepare(THD *thd)
837
834
{
838
835
  int error=0, all=1;
839
 
  Session_TRANS *trans=all ? &session->transaction.all : &session->transaction.stmt;
 
836
  THD_TRANS *trans=all ? &thd->transaction.all : &thd->transaction.stmt;
840
837
  Ha_trx_info *ha_info= trans->ha_list;
841
838
  if (ha_info)
842
839
  {
844
841
    {
845
842
      int err;
846
843
      handlerton *ht= ha_info->ht();
847
 
      status_var_increment(session->status_var.ha_prepare_count);
 
844
      status_var_increment(thd->status_var.ha_prepare_count);
848
845
      if (ht->prepare)
849
846
      {
850
 
        if ((err= ht->prepare(ht, session, all)))
 
847
        if ((err= ht->prepare(ht, thd, all)))
851
848
        {
852
849
          my_error(ER_ERROR_DURING_COMMIT, MYF(0), err);
853
 
          ha_rollback_trans(session, all);
 
850
          ha_rollback_trans(thd, all);
854
851
          error=1;
855
852
          break;
856
853
        }
857
854
      }
858
855
      else
859
856
      {
860
 
        push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
857
        push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
861
858
                            ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
862
859
                            ha_resolve_storage_engine_name(ht));
863
860
      }
882
879
 
883
880
static
884
881
bool
885
 
ha_check_and_coalesce_trx_read_only(Session *session, Ha_trx_info *ha_list,
 
882
ha_check_and_coalesce_trx_read_only(THD *thd, Ha_trx_info *ha_list,
886
883
                                    bool all)
887
884
{
888
885
  /* The number of storage engines that have actual changes. */
896
893
 
897
894
    if (! all)
898
895
    {
899
 
      Ha_trx_info *ha_info_all= &session->ha_data[ha_info->ht()->slot].ha_info[1];
 
896
      Ha_trx_info *ha_info_all= &thd->ha_data[ha_info->ht()->slot].ha_info[1];
900
897
      assert(ha_info != ha_info_all);
901
898
      /*
902
899
        Merge read-only/read-write information about statement
903
900
        transaction to its enclosing normal transaction. Do this
904
901
        only if in a real transaction -- that is, if we know
905
 
        that ha_info_all is registered in session->transaction.all.
 
902
        that ha_info_all is registered in thd->transaction.all.
906
903
        Since otherwise we only clutter the normal transaction flags.
907
904
      */
908
905
      if (ha_info_all->is_started()) /* false if autocommit. */
936
933
    stored functions or triggers. So we simply do nothing now.
937
934
    TODO: This should be fixed in later ( >= 5.1) releases.
938
935
*/
939
 
int ha_commit_trans(Session *session, bool all)
 
936
int ha_commit_trans(THD *thd, bool all)
940
937
{
941
938
  int error= 0, cookie= 0;
942
939
  /*
943
940
    'all' means that this is either an explicit commit issued by
944
941
    user, or an implicit commit issued by a DDL.
945
942
  */
946
 
  Session_TRANS *trans= all ? &session->transaction.all : &session->transaction.stmt;
947
 
  bool is_real_trans= all || session->transaction.all.ha_list == 0;
 
943
  THD_TRANS *trans= all ? &thd->transaction.all : &thd->transaction.stmt;
 
944
  bool is_real_trans= all || thd->transaction.all.ha_list == 0;
948
945
  Ha_trx_info *ha_info= trans->ha_list;
949
 
  my_xid xid= session->transaction.xid_state.xid.get_my_xid();
 
946
  my_xid xid= thd->transaction.xid_state.xid.get_my_xid();
950
947
 
951
948
  /*
952
949
    We must not commit the normal transaction if a statement
954
951
    flags will not get propagated to its normal transaction's
955
952
    counterpart.
956
953
  */
957
 
  assert(session->transaction.stmt.ha_list == NULL ||
958
 
              trans == &session->transaction.stmt);
 
954
  assert(thd->transaction.stmt.ha_list == NULL ||
 
955
              trans == &thd->transaction.stmt);
959
956
 
 
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
  }
960
977
  if (ha_info)
961
978
  {
962
979
    bool must_2pc;
963
980
 
964
 
    if (is_real_trans && wait_if_global_read_lock(session, 0, 0))
 
981
    if (is_real_trans && wait_if_global_read_lock(thd, 0, 0))
965
982
    {
966
 
      ha_rollback_trans(session, all);
 
983
      ha_rollback_trans(thd, all);
967
984
      return(1);
968
985
    }
969
986
 
970
987
    if (   is_real_trans
971
988
        && opt_readonly
972
 
        && ! session->slave_thread
 
989
        && ! thd->slave_thread
973
990
       )
974
991
    {
975
992
      my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--read-only");
976
 
      ha_rollback_trans(session, all);
 
993
      ha_rollback_trans(thd, all);
977
994
      error= 1;
978
995
      goto end;
979
996
    }
980
997
 
981
 
    must_2pc= ha_check_and_coalesce_trx_read_only(session, ha_info, all);
 
998
    must_2pc= ha_check_and_coalesce_trx_read_only(thd, ha_info, all);
982
999
 
983
1000
    if (!trans->no_2pc && must_2pc)
984
1001
    {
997
1014
          Sic: we know that prepare() is not NULL since otherwise
998
1015
          trans->no_2pc would have been set.
999
1016
        */
1000
 
        if ((err= ht->prepare(ht, session, all)))
 
1017
        if ((err= ht->prepare(ht, thd, all)))
1001
1018
        {
1002
1019
          my_error(ER_ERROR_DURING_COMMIT, MYF(0), err);
1003
1020
          error= 1;
1004
1021
        }
1005
 
        status_var_increment(session->status_var.ha_prepare_count);
 
1022
        status_var_increment(thd->status_var.ha_prepare_count);
1006
1023
      }
1007
1024
      if (error || (is_real_trans && xid &&
1008
 
                    (error= !(cookie= tc_log->log_xid(session, xid)))))
 
1025
                    (error= !(cookie= tc_log->log_xid(thd, xid)))))
1009
1026
      {
1010
 
        ha_rollback_trans(session, all);
 
1027
        ha_rollback_trans(thd, all);
1011
1028
        error= 1;
1012
1029
        goto end;
1013
1030
      }
1014
1031
    }
1015
 
    error=ha_commit_one_phase(session, all) ? (cookie ? 2 : 1) : 0;
 
1032
    error=ha_commit_one_phase(thd, all) ? (cookie ? 2 : 1) : 0;
1016
1033
    if (cookie)
1017
1034
      tc_log->unlog(cookie, xid);
1018
1035
end:
1019
1036
    if (is_real_trans)
1020
 
      start_waiting_global_read_lock(session);
 
1037
      start_waiting_global_read_lock(thd);
1021
1038
  }
1022
1039
  return(error);
1023
1040
}
1026
1043
  @note
1027
1044
  This function does not care about global read lock. A caller should.
1028
1045
*/
1029
 
int ha_commit_one_phase(Session *session, bool all)
 
1046
int ha_commit_one_phase(THD *thd, bool all)
1030
1047
{
1031
1048
  int error=0;
1032
 
  Session_TRANS *trans=all ? &session->transaction.all : &session->transaction.stmt;
1033
 
  bool is_real_trans=all || session->transaction.all.ha_list == 0;
 
1049
  THD_TRANS *trans=all ? &thd->transaction.all : &thd->transaction.stmt;
 
1050
  bool is_real_trans=all || thd->transaction.all.ha_list == 0;
1034
1051
  Ha_trx_info *ha_info= trans->ha_list, *ha_info_next;
1035
1052
  if (ha_info)
1036
1053
  {
1038
1055
    {
1039
1056
      int err;
1040
1057
      handlerton *ht= ha_info->ht();
1041
 
      if ((err= ht->commit(ht, session, all)))
 
1058
      if ((err= ht->commit(ht, thd, all)))
1042
1059
      {
1043
1060
        my_error(ER_ERROR_DURING_COMMIT, MYF(0), err);
1044
1061
        error=1;
1045
1062
      }
1046
 
      status_var_increment(session->status_var.ha_commit_count);
 
1063
      status_var_increment(thd->status_var.ha_commit_count);
1047
1064
      ha_info_next= ha_info->next();
1048
1065
      ha_info->reset(); /* keep it conveniently zero-filled */
1049
1066
    }
1050
1067
    trans->ha_list= 0;
1051
1068
    trans->no_2pc=0;
1052
1069
    if (is_real_trans)
1053
 
      session->transaction.xid_state.xid.null();
 
1070
      thd->transaction.xid_state.xid.null();
1054
1071
    if (all)
1055
1072
    {
1056
 
      session->variables.tx_isolation=session->session_tx_isolation;
1057
 
      session->transaction.cleanup();
 
1073
      thd->variables.tx_isolation=thd->session_tx_isolation;
 
1074
      thd->transaction.cleanup();
1058
1075
    }
1059
1076
  }
1060
1077
  return(error);
1061
1078
}
1062
1079
 
1063
1080
 
1064
 
int ha_rollback_trans(Session *session, bool all)
 
1081
int ha_rollback_trans(THD *thd, bool all)
1065
1082
{
1066
1083
  int error=0;
1067
 
  Session_TRANS *trans=all ? &session->transaction.all : &session->transaction.stmt;
 
1084
  THD_TRANS *trans=all ? &thd->transaction.all : &thd->transaction.stmt;
1068
1085
  Ha_trx_info *ha_info= trans->ha_list, *ha_info_next;
1069
 
  bool is_real_trans=all || session->transaction.all.ha_list == 0;
 
1086
  bool is_real_trans=all || thd->transaction.all.ha_list == 0;
1070
1087
 
1071
1088
  /*
1072
1089
    We must not rollback the normal transaction if a statement
1073
1090
    transaction is pending.
1074
1091
  */
1075
 
  assert(session->transaction.stmt.ha_list == NULL ||
1076
 
              trans == &session->transaction.stmt);
 
1092
  assert(thd->transaction.stmt.ha_list == NULL ||
 
1093
              trans == &thd->transaction.stmt);
1077
1094
 
 
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
  }
1078
1108
  if (ha_info)
1079
1109
  {
1080
1110
    for (; ha_info; ha_info= ha_info_next)
1081
1111
    {
1082
1112
      int err;
1083
1113
      handlerton *ht= ha_info->ht();
1084
 
      if ((err= ht->rollback(ht, session, all)))
 
1114
      if ((err= ht->rollback(ht, thd, all)))
1085
1115
      { // cannot happen
1086
1116
        my_error(ER_ERROR_DURING_ROLLBACK, MYF(0), err);
1087
1117
        error=1;
1088
1118
      }
1089
 
      status_var_increment(session->status_var.ha_rollback_count);
 
1119
      status_var_increment(thd->status_var.ha_rollback_count);
1090
1120
      ha_info_next= ha_info->next();
1091
1121
      ha_info->reset(); /* keep it conveniently zero-filled */
1092
1122
    }
1093
1123
    trans->ha_list= 0;
1094
1124
    trans->no_2pc=0;
1095
1125
    if (is_real_trans)
1096
 
      session->transaction.xid_state.xid.null();
 
1126
      thd->transaction.xid_state.xid.null();
1097
1127
    if (all)
1098
1128
    {
1099
 
      session->variables.tx_isolation=session->session_tx_isolation;
1100
 
      session->transaction.cleanup();
 
1129
      thd->variables.tx_isolation=thd->session_tx_isolation;
 
1130
      thd->transaction.cleanup();
1101
1131
    }
1102
1132
  }
1103
1133
  if (all)
1104
 
    session->transaction_rollback_request= false;
 
1134
    thd->transaction_rollback_request= false;
1105
1135
 
1106
1136
  /*
1107
1137
    If a non-transactional table was updated, warn; don't warn if this is a
1112
1142
    the error log; but we don't want users to wonder why they have this
1113
1143
    message in the error log, so we don't send it.
1114
1144
  */
1115
 
  if (is_real_trans && session->transaction.all.modified_non_trans_table &&
1116
 
      !session->slave_thread && session->killed != Session::KILL_CONNECTION)
1117
 
    push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
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,
1118
1148
                 ER_WARNING_NOT_COMPLETE_ROLLBACK,
1119
1149
                 ER(ER_WARNING_NOT_COMPLETE_ROLLBACK));
1120
1150
  return(error);
1131
1161
    the user has used LOCK TABLES then that mechanism does not know to do the
1132
1162
    commit.
1133
1163
*/
1134
 
int ha_autocommit_or_rollback(Session *session, int error)
 
1164
int ha_autocommit_or_rollback(THD *thd, int error)
1135
1165
{
1136
 
  if (session->transaction.stmt.ha_list)
 
1166
  if (thd->transaction.stmt.ha_list)
1137
1167
  {
1138
1168
    if (!error)
1139
1169
    {
1140
 
      if (ha_commit_trans(session, 0))
 
1170
      if (ha_commit_trans(thd, 0))
1141
1171
        error=1;
1142
1172
    }
1143
1173
    else 
1144
1174
    {
1145
 
      (void) ha_rollback_trans(session, 0);
1146
 
      if (session->transaction_rollback_request)
1147
 
        (void) ha_rollback(session);
 
1175
      (void) ha_rollback_trans(thd, 0);
 
1176
      if (thd->transaction_rollback_request && !thd->in_sub_stmt)
 
1177
        (void) ha_rollback(thd);
1148
1178
    }
1149
1179
 
1150
 
    session->variables.tx_isolation=session->session_tx_isolation;
 
1180
    thd->variables.tx_isolation=thd->session_tx_isolation;
1151
1181
  }
1152
1182
  return(error);
1153
1183
}
1158
1188
  int result;
1159
1189
};
1160
1190
 
1161
 
static bool xacommit_handlerton(Session *unused1 __attribute__((unused)),
 
1191
static bool xacommit_handlerton(THD *unused1 __attribute__((unused)),
1162
1192
                                plugin_ref plugin,
1163
1193
                                void *arg)
1164
1194
{
1171
1201
  return false;
1172
1202
}
1173
1203
 
1174
 
static bool xarollback_handlerton(Session *unused1 __attribute__((unused)),
 
1204
static bool xarollback_handlerton(THD *unused1 __attribute__((unused)),
1175
1205
                                  plugin_ref plugin,
1176
1206
                                  void *arg)
1177
1207
{
1221
1251
  bool dry_run;
1222
1252
};
1223
1253
 
1224
 
static bool xarecover_handlerton(Session *unused __attribute__((unused)),
 
1254
static bool xarecover_handlerton(THD *unused __attribute__((unused)),
1225
1255
                                 plugin_ref plugin,
1226
1256
                                 void *arg)
1227
1257
{
1251
1281
        }
1252
1282
        // recovery mode
1253
1283
        if (info->commit_list ?
1254
 
            hash_search(info->commit_list, (unsigned char *)&x, sizeof(x)) != 0 :
 
1284
            hash_search(info->commit_list, (uchar *)&x, sizeof(x)) != 0 :
1255
1285
            tc_heuristic_recover == TC_HEURISTIC_RECOVER_COMMIT)
1256
1286
        {
1257
1287
          hton->commit_by_xid(hton, info->list+i);
1315
1345
  plugin_foreach(NULL, xarecover_handlerton, 
1316
1346
                 DRIZZLE_STORAGE_ENGINE_PLUGIN, &info);
1317
1347
 
1318
 
  free((unsigned char*)info.list);
 
1348
  my_free((uchar*)info.list, MYF(0));
1319
1349
  if (info.found_foreign_xids)
1320
1350
    sql_print_warning(_("Found %d prepared XA transactions"), 
1321
1351
                      info.found_foreign_xids);
1343
1373
    so mysql_xa_recover does not filter XID's to ensure uniqueness.
1344
1374
    It can be easily fixed later, if necessary.
1345
1375
*/
1346
 
bool mysql_xa_recover(Session *session)
 
1376
bool mysql_xa_recover(THD *thd)
1347
1377
{
1348
1378
  List<Item> field_list;
1349
 
  Protocol *protocol= session->protocol;
 
1379
  Protocol *protocol= thd->protocol;
1350
1380
  int i=0;
1351
1381
  XID_STATE *xs;
1352
1382
 
1379
1409
  }
1380
1410
 
1381
1411
  pthread_mutex_unlock(&LOCK_xid_cache);
1382
 
  my_eof(session);
 
1412
  my_eof(thd);
1383
1413
  return(0);
1384
1414
}
1385
1415
 
1387
1417
  @details
1388
1418
  This function should be called when MySQL sends rows of a SELECT result set
1389
1419
  or the EOF mark to the client. It releases a possible adaptive hash index
1390
 
  S-latch held by session in InnoDB and also releases a possible InnoDB query
1391
 
  FIFO ticket to enter InnoDB. To save CPU time, InnoDB allows a session to
 
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
1392
1422
  keep them over several calls of the InnoDB handler interface when a join
1393
1423
  is executed. But when we let the control to pass to the client they have
1394
1424
  to be released because if the application program uses mysql_use_result(),
1396
1426
  performs another SQL query. In MySQL-4.1 this is even more important because
1397
1427
  there a connection can have several SELECT queries open at the same time.
1398
1428
 
1399
 
  @param session           the thread handle of the current connection
 
1429
  @param thd           the thread handle of the current connection
1400
1430
 
1401
1431
  @return
1402
1432
    always 0
1403
1433
*/
1404
 
static bool release_temporary_latches(Session *session, plugin_ref plugin,
 
1434
static bool release_temporary_latches(THD *thd, plugin_ref plugin,
1405
1435
                                      void *unused __attribute__((unused)))
1406
1436
{
1407
1437
  handlerton *hton= plugin_data(plugin, handlerton *);
1408
1438
 
1409
1439
  if (hton->state == SHOW_OPTION_YES && hton->release_temporary_latches)
1410
 
    hton->release_temporary_latches(hton, session);
 
1440
    hton->release_temporary_latches(hton, thd);
1411
1441
 
1412
1442
  return false;
1413
1443
}
1414
1444
 
1415
1445
 
1416
 
int ha_release_temporary_latches(Session *session)
 
1446
int ha_release_temporary_latches(THD *thd)
1417
1447
{
1418
 
  plugin_foreach(session, release_temporary_latches, DRIZZLE_STORAGE_ENGINE_PLUGIN, 
 
1448
  plugin_foreach(thd, release_temporary_latches, DRIZZLE_STORAGE_ENGINE_PLUGIN, 
1419
1449
                 NULL);
1420
1450
 
1421
1451
  return 0;
1422
1452
}
1423
1453
 
1424
 
int ha_rollback_to_savepoint(Session *session, SAVEPOINT *sv)
 
1454
int ha_rollback_to_savepoint(THD *thd, SAVEPOINT *sv)
1425
1455
{
1426
1456
  int error=0;
1427
 
  Session_TRANS *trans= &session->transaction.all;
 
1457
  THD_TRANS *trans= (thd->in_sub_stmt ? &thd->transaction.stmt :
 
1458
                                        &thd->transaction.all);
1428
1459
  Ha_trx_info *ha_info, *ha_info_next;
1429
1460
 
1430
1461
  trans->no_2pc=0;
1438
1469
    handlerton *ht= ha_info->ht();
1439
1470
    assert(ht);
1440
1471
    assert(ht->savepoint_set != 0);
1441
 
    if ((err= ht->savepoint_rollback(ht, session,
1442
 
                                     (unsigned char *)(sv+1)+ht->savepoint_offset)))
 
1472
    if ((err= ht->savepoint_rollback(ht, thd,
 
1473
                                     (uchar *)(sv+1)+ht->savepoint_offset)))
1443
1474
    { // cannot happen
1444
1475
      my_error(ER_ERROR_DURING_ROLLBACK, MYF(0), err);
1445
1476
      error=1;
1446
1477
    }
1447
 
    status_var_increment(session->status_var.ha_savepoint_rollback_count);
 
1478
    status_var_increment(thd->status_var.ha_savepoint_rollback_count);
1448
1479
    trans->no_2pc|= ht->prepare == 0;
1449
1480
  }
1450
1481
  /*
1456
1487
  {
1457
1488
    int err;
1458
1489
    handlerton *ht= ha_info->ht();
1459
 
    if ((err= ht->rollback(ht, session, !(0))))
 
1490
    if ((err= ht->rollback(ht, thd, !thd->in_sub_stmt)))
1460
1491
    { // cannot happen
1461
1492
      my_error(ER_ERROR_DURING_ROLLBACK, MYF(0), err);
1462
1493
      error=1;
1463
1494
    }
1464
 
    status_var_increment(session->status_var.ha_rollback_count);
 
1495
    status_var_increment(thd->status_var.ha_rollback_count);
1465
1496
    ha_info_next= ha_info->next();
1466
1497
    ha_info->reset(); /* keep it conveniently zero-filled */
1467
1498
  }
1475
1506
  section "4.33.4 SQL-statements and transaction states",
1476
1507
  SAVEPOINT is *not* transaction-initiating SQL-statement
1477
1508
*/
1478
 
int ha_savepoint(Session *session, SAVEPOINT *sv)
 
1509
int ha_savepoint(THD *thd, SAVEPOINT *sv)
1479
1510
{
1480
1511
  int error=0;
1481
 
  Session_TRANS *trans= &session->transaction.all;
 
1512
  THD_TRANS *trans= (thd->in_sub_stmt ? &thd->transaction.stmt :
 
1513
                                        &thd->transaction.all);
1482
1514
  Ha_trx_info *ha_info= trans->ha_list;
1483
1515
  for (; ha_info; ha_info= ha_info->next())
1484
1516
  {
1491
1523
      error=1;
1492
1524
      break;
1493
1525
    }
1494
 
    if ((err= ht->savepoint_set(ht, session, (unsigned char *)(sv+1)+ht->savepoint_offset)))
 
1526
    if ((err= ht->savepoint_set(ht, thd, (uchar *)(sv+1)+ht->savepoint_offset)))
1495
1527
    { // cannot happen
1496
1528
      my_error(ER_GET_ERRNO, MYF(0), err);
1497
1529
      error=1;
1498
1530
    }
1499
 
    status_var_increment(session->status_var.ha_savepoint_count);
 
1531
    status_var_increment(thd->status_var.ha_savepoint_count);
1500
1532
  }
1501
1533
  /*
1502
1534
    Remember the list of registered storage engines. All new
1506
1538
  return(error);
1507
1539
}
1508
1540
 
1509
 
int ha_release_savepoint(Session *session, SAVEPOINT *sv)
 
1541
int ha_release_savepoint(THD *thd, SAVEPOINT *sv)
1510
1542
{
1511
1543
  int error=0;
1512
1544
  Ha_trx_info *ha_info= sv->ha_list;
1519
1551
    assert(ht);
1520
1552
    if (!ht->savepoint_release)
1521
1553
      continue;
1522
 
    if ((err= ht->savepoint_release(ht, session,
1523
 
                                    (unsigned char *)(sv+1) + ht->savepoint_offset)))
 
1554
    if ((err= ht->savepoint_release(ht, thd,
 
1555
                                    (uchar *)(sv+1) + ht->savepoint_offset)))
1524
1556
    { // cannot happen
1525
1557
      my_error(ER_GET_ERRNO, MYF(0), err);
1526
1558
      error=1;
1530
1562
}
1531
1563
 
1532
1564
 
1533
 
static bool snapshot_handlerton(Session *session, plugin_ref plugin, void *arg)
 
1565
static bool snapshot_handlerton(THD *thd, plugin_ref plugin, void *arg)
1534
1566
{
1535
1567
  handlerton *hton= plugin_data(plugin, handlerton *);
1536
1568
  if (hton->state == SHOW_OPTION_YES &&
1537
1569
      hton->start_consistent_snapshot)
1538
1570
  {
1539
 
    hton->start_consistent_snapshot(hton, session);
 
1571
    hton->start_consistent_snapshot(hton, thd);
1540
1572
    *((bool *)arg)= false;
1541
1573
  }
1542
1574
  return false;
1543
1575
}
1544
1576
 
1545
 
int ha_start_consistent_snapshot(Session *session)
 
1577
int ha_start_consistent_snapshot(THD *thd)
1546
1578
{
1547
1579
  bool warn= true;
1548
1580
 
1549
 
  plugin_foreach(session, snapshot_handlerton, DRIZZLE_STORAGE_ENGINE_PLUGIN, &warn);
 
1581
  plugin_foreach(thd, snapshot_handlerton, DRIZZLE_STORAGE_ENGINE_PLUGIN, &warn);
1550
1582
 
1551
1583
  /*
1552
1584
    Same idea as when one wants to CREATE TABLE in one engine which does not
1553
1585
    exist:
1554
1586
  */
1555
1587
  if (warn)
1556
 
    push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
 
1588
    push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
1557
1589
                 "This MySQL server does not support any "
1558
1590
                 "consistent-read capable storage engine");
1559
1591
  return 0;
1560
1592
}
1561
1593
 
1562
1594
 
1563
 
static bool flush_handlerton(Session *session __attribute__((unused)),
 
1595
static bool flush_handlerton(THD *thd __attribute__((unused)),
1564
1596
                             plugin_ref plugin,
1565
1597
                             void *arg __attribute__((unused)))
1566
1598
{
1617
1649
struct Ha_delete_table_error_handler: public Internal_error_handler
1618
1650
{
1619
1651
public:
1620
 
  virtual bool handle_error(uint32_t sql_errno,
 
1652
  virtual bool handle_error(uint sql_errno,
1621
1653
                            const char *message,
1622
1654
                            DRIZZLE_ERROR::enum_warning_level level,
1623
 
                            Session *session);
 
1655
                            THD *thd);
1624
1656
  char buff[DRIZZLE_ERRMSG_SIZE];
1625
1657
};
1626
1658
 
1627
1659
 
1628
1660
bool
1629
1661
Ha_delete_table_error_handler::
1630
 
handle_error(uint32_t sql_errno  __attribute__((unused)),
 
1662
handle_error(uint sql_errno  __attribute__((unused)),
1631
1663
             const char *message,
1632
1664
             DRIZZLE_ERROR::enum_warning_level level __attribute__((unused)),
1633
 
             Session *session __attribute__((unused)))
 
1665
             THD *thd __attribute__((unused)))
1634
1666
{
1635
1667
  /* Grab the error message */
1636
1668
  strmake(buff, message, sizeof(buff)-1);
1642
1674
  This should return ENOENT if the file doesn't exists.
1643
1675
  The .frm file will be deleted only if we return 0 or ENOENT
1644
1676
*/
1645
 
int ha_delete_table(Session *session, handlerton *table_type, const char *path,
 
1677
int ha_delete_table(THD *thd, handlerton *table_type, const char *path,
1646
1678
                    const char *db, const char *alias, bool generate_warning)
1647
1679
{
1648
1680
  handler *file;
1657
1689
 
1658
1690
  /* DB_TYPE_UNKNOWN is used in ALTER Table when renaming only .frm files */
1659
1691
  if (table_type == NULL ||
1660
 
      ! (file=get_new_handler((TABLE_SHARE*)0, session->mem_root, table_type)))
 
1692
      ! (file=get_new_handler((TABLE_SHARE*)0, thd->mem_root, table_type)))
1661
1693
    return(ENOENT);
1662
1694
 
1663
1695
  path= check_lowercase_names(file, path, tmp_path);
1682
1714
 
1683
1715
    file->change_table_ptr(&dummy_table, &dummy_share);
1684
1716
 
1685
 
    session->push_internal_handler(&ha_delete_table_error_handler);
 
1717
    thd->push_internal_handler(&ha_delete_table_error_handler);
1686
1718
    file->print_error(error, 0);
1687
1719
 
1688
 
    session->pop_internal_handler();
 
1720
    thd->pop_internal_handler();
1689
1721
 
1690
1722
    /*
1691
1723
      XXX: should we convert *all* errors to warnings here?
1692
1724
      What if the error is fatal?
1693
1725
    */
1694
 
    push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_ERROR, error,
 
1726
    push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_ERROR, error,
1695
1727
                ha_delete_table_error_handler.buff);
1696
1728
  }
1697
1729
  delete file;
1709
1741
    on this->table->mem_root and we will not be able to reclaim that memory 
1710
1742
    when the clone handler object is destroyed.
1711
1743
  */
1712
 
  if (!(new_handler->ref= (unsigned char*) alloc_root(mem_root, ALIGN_SIZE(ref_length)*2)))
 
1744
  if (!(new_handler->ref= (uchar*) alloc_root(mem_root, ALIGN_SIZE(ref_length)*2)))
1713
1745
    return NULL;
1714
1746
  if (new_handler && !new_handler->ha_open(table,
1715
1747
                                           table->s->normalized_path.str,
1726
1758
  status_var_increment(table->in_use->status_var.*offset);
1727
1759
}
1728
1760
 
1729
 
void **handler::ha_data(Session *session) const
 
1761
void **handler::ha_data(THD *thd) const
1730
1762
{
1731
 
  return session_ha_data(session, ht);
 
1763
  return thd_ha_data(thd, ht);
1732
1764
}
1733
1765
 
1734
 
Session *handler::ha_session(void) const
 
1766
THD *handler::ha_thd(void) const
1735
1767
{
1736
 
  assert(!table || !table->in_use || table->in_use == current_session);
1737
 
  return (table && table->in_use) ? table->in_use : current_session;
 
1768
  assert(!table || !table->in_use || table->in_use == current_thd);
 
1769
  return (table && table->in_use) ? table->in_use : current_thd;
1738
1770
}
1739
1771
 
1740
1772
/**
1772
1804
    (void) extra(HA_EXTRA_NO_READCHECK);        // Not needed in SQL
1773
1805
 
1774
1806
    /* ref is already allocated for us if we're called from handler::clone() */
1775
 
    if (!ref && !(ref= (unsigned char*) alloc_root(&table->mem_root, 
 
1807
    if (!ref && !(ref= (uchar*) alloc_root(&table->mem_root, 
1776
1808
                                          ALIGN_SIZE(ref_length)*2)))
1777
1809
    {
1778
1810
      close();
1792
1824
  handlers for random position
1793
1825
*/
1794
1826
 
1795
 
int handler::rnd_pos_by_record(unsigned char *record)
 
1827
int handler::rnd_pos_by_record(uchar *record)
1796
1828
{
1797
1829
  register int error;
1798
1830
 
1811
1843
  This is never called for InnoDB tables, as these table types
1812
1844
  has the HA_STATS_RECORDS_IS_EXACT set.
1813
1845
*/
1814
 
int handler::read_first_row(unsigned char * buf, uint32_t primary_key)
 
1846
int handler::read_first_row(uchar * buf, uint primary_key)
1815
1847
{
1816
1848
  register int error;
1817
1849
 
1866
1898
void handler::adjust_next_insert_id_after_explicit_value(uint64_t nr)
1867
1899
{
1868
1900
  /*
1869
 
    If we have set Session::next_insert_id previously and plan to insert an
 
1901
    If we have set THD::next_insert_id previously and plan to insert an
1870
1902
    explicitely-specified value larger than this, we need to increase
1871
 
    Session::next_insert_id to be greater than the explicit value.
 
1903
    THD::next_insert_id to be greater than the explicit value.
1872
1904
  */
1873
1905
  if ((next_insert_id > 0) && (nr >= next_insert_id))
1874
1906
    set_next_insert_id(compute_next_insert_id(nr, &table->in_use->variables));
1944
1976
    again to reserve a new interval.
1945
1977
 
1946
1978
  - In both cases, the reserved intervals are remembered in
1947
 
    session->auto_inc_intervals_in_cur_stmt_for_binlog if statement-based
 
1979
    thd->auto_inc_intervals_in_cur_stmt_for_binlog if statement-based
1948
1980
    binlogging; the last reserved interval is remembered in
1949
1981
    auto_inc_interval_for_cur_row.
1950
1982
 
1958
1990
    start counting from the inserted value.
1959
1991
 
1960
1992
    This function's "outputs" are: the table's auto_increment field is filled
1961
 
    with a value, session->next_insert_id is filled with the value to use for the
 
1993
    with a value, thd->next_insert_id is filled with the value to use for the
1962
1994
    next row, if a value was autogenerated for the current row it is stored in
1963
 
    session->insert_id_for_cur_row, if get_auto_increment() was called
1964
 
    session->auto_inc_interval_for_cur_row is modified, if that interval is not
1965
 
    present in session->auto_inc_intervals_in_cur_stmt_for_binlog it is added to
 
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
1966
1998
    this list.
1967
1999
 
1968
2000
  @todo
1989
2021
{
1990
2022
  uint64_t nr, nb_reserved_values;
1991
2023
  bool append= false;
1992
 
  Session *session= table->in_use;
1993
 
  struct system_variables *variables= &session->variables;
 
2024
  THD *thd= table->in_use;
 
2025
  struct system_variables *variables= &thd->variables;
1994
2026
 
1995
2027
  /*
1996
2028
    next_insert_id is a "cursor" into the reserved interval, it may go greater
2015
2047
  {
2016
2048
    /* next_insert_id is beyond what is reserved, so we reserve more. */
2017
2049
    const Discrete_interval *forced=
2018
 
      session->auto_inc_intervals_forced.get_next();
 
2050
      thd->auto_inc_intervals_forced.get_next();
2019
2051
    if (forced != NULL)
2020
2052
    {
2021
2053
      nr= forced->minimum();
2027
2059
        handler::estimation_rows_to_insert was set by
2028
2060
        handler::ha_start_bulk_insert(); if 0 it means "unknown".
2029
2061
      */
2030
 
      uint32_t nb_already_reserved_intervals=
2031
 
        session->auto_inc_intervals_in_cur_stmt_for_binlog.nb_elements();
 
2062
      uint nb_already_reserved_intervals=
 
2063
        thd->auto_inc_intervals_in_cur_stmt_for_binlog.nb_elements();
2032
2064
      uint64_t nb_desired_values;
2033
2065
      /*
2034
2066
        If an estimation was given to the engine:
2087
2119
    /*
2088
2120
      first test if the query was aborted due to strict mode constraints
2089
2121
    */
2090
 
    if (session->killed == Session::KILL_BAD_DATA)
 
2122
    if (thd->killed == THD::KILL_BAD_DATA)
2091
2123
      return(HA_ERR_AUTOINC_ERANGE);
2092
2124
 
2093
2125
    /*
2107
2139
    auto_inc_interval_for_cur_row.replace(nr, nb_reserved_values,
2108
2140
                                          variables->auto_increment_increment);
2109
2141
    /* Row-based replication does not need to store intervals in binlog */
2110
 
    if (!session->current_stmt_binlog_row_based)
2111
 
        session->auto_inc_intervals_in_cur_stmt_for_binlog.append(auto_inc_interval_for_cur_row.minimum(),
 
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(),
2112
2144
                                                              auto_inc_interval_for_cur_row.values(),
2113
2145
                                                              variables->auto_increment_increment);
2114
2146
  }
2190
2222
  }
2191
2223
  else
2192
2224
  {
2193
 
    unsigned char key[MAX_KEY_LENGTH];
 
2225
    uchar key[MAX_KEY_LENGTH];
2194
2226
    key_copy(key, table->record[0],
2195
2227
             table->key_info + table->s->next_number_index,
2196
2228
             table->s->next_number_key_offset);
2234
2266
}
2235
2267
 
2236
2268
 
2237
 
void handler::print_keydup_error(uint32_t key_nr, const char *msg)
 
2269
void handler::print_keydup_error(uint key_nr, const char *msg)
2238
2270
{
2239
2271
  /* Write the duplicated key in the error message */
2240
2272
  char key[MAX_KEY_LENGTH];
2250
2282
  {
2251
2283
    /* Table is opened and defined at this point */
2252
2284
    key_unpack(&str,table,(uint) key_nr);
2253
 
    uint32_t max_length=DRIZZLE_ERRMSG_SIZE-(uint) strlen(msg);
 
2285
    uint max_length=DRIZZLE_ERRMSG_SIZE-(uint) strlen(msg);
2254
2286
    if (str.length() >= max_length)
2255
2287
    {
2256
2288
      str.length(max_length-4);
2294
2326
    break;
2295
2327
  case HA_ERR_FOUND_DUPP_KEY:
2296
2328
  {
2297
 
    uint32_t key_nr=get_dup_key(error);
 
2329
    uint key_nr=get_dup_key(error);
2298
2330
    if ((int) key_nr >= 0)
2299
2331
    {
2300
2332
      print_keydup_error(key_nr, ER(ER_DUP_ENTRY_WITH_KEY_NAME));
2305
2337
  }
2306
2338
  case HA_ERR_FOREIGN_DUPLICATE_KEY:
2307
2339
  {
2308
 
    uint32_t key_nr= get_dup_key(error);
 
2340
    uint key_nr= get_dup_key(error);
2309
2341
    if ((int) key_nr >= 0)
2310
2342
    {
2311
 
      uint32_t max_length;
 
2343
      uint max_length;
2312
2344
      /* Write the key in the error message */
2313
2345
      char key[MAX_KEY_LENGTH];
2314
2346
      String str(key,sizeof(key),system_charset_info);
2407
2439
  case HA_ERR_DROP_INDEX_FK:
2408
2440
  {
2409
2441
    const char *ptr= "???";
2410
 
    uint32_t key_nr= get_dup_key(error);
 
2442
    uint key_nr= get_dup_key(error);
2411
2443
    if ((int) key_nr >= 0)
2412
2444
      ptr= table->key_info[key_nr].name;
2413
2445
    my_error(ER_DROP_INDEX_FK, MYF(0), ptr);
2525
2557
  if (table->s->mysql_version == DRIZZLE_VERSION_ID)
2526
2558
    return(0);
2527
2559
 
2528
 
  strxmov(path, table->s->normalized_path.str, reg_ext, NULL);
 
2560
  strxmov(path, table->s->normalized_path.str, reg_ext, NullS);
2529
2561
 
2530
 
  if ((file= my_open(path, O_RDWR, MYF(MY_WME))) >= 0)
 
2562
  if ((file= my_open(path, O_RDWR|O_BINARY, MYF(MY_WME))) >= 0)
2531
2563
  {
2532
 
    unsigned char version[4];
 
2564
    uchar version[4];
2533
2565
    char *key= table->s->table_cache_key.str;
2534
 
    uint32_t key_length= table->s->table_cache_key.length;
 
2566
    uint key_length= table->s->table_cache_key.length;
2535
2567
    Table *entry;
2536
2568
    HASH_SEARCH_STATE state;
2537
2569
 
2538
2570
    int4store(version, DRIZZLE_VERSION_ID);
2539
2571
 
2540
 
    if (pwrite(file, (unsigned char*)version, 4, 51L) == 0)
 
2572
    if (pwrite(file, (uchar*)version, 4, 51L) == 0)
2541
2573
    {
2542
2574
      result= false;
2543
2575
      goto err;
2544
2576
    }
2545
2577
 
2546
 
    for (entry=(Table*) hash_first(&open_cache,(unsigned char*) key,key_length, &state);
 
2578
    for (entry=(Table*) hash_first(&open_cache,(uchar*) key,key_length, &state);
2547
2579
         entry;
2548
 
         entry= (Table*) hash_next(&open_cache,(unsigned char*) key,key_length, &state))
 
2580
         entry= (Table*) hash_next(&open_cache,(uchar*) key,key_length, &state))
2549
2581
      entry->s->mysql_version= DRIZZLE_VERSION_ID;
2550
2582
  }
2551
2583
err:
2552
2584
  if (file >= 0)
2553
 
    my_close(file,MYF(MY_WME));
 
2585
    VOID(my_close(file,MYF(MY_WME)));
2554
2586
  return(result);
2555
2587
}
2556
2588
 
2560
2592
  @return
2561
2593
    key if error because of duplicated keys
2562
2594
*/
2563
 
uint32_t handler::get_dup_key(int error)
 
2595
uint handler::get_dup_key(int error)
2564
2596
{
2565
2597
  table->file->errkey  = (uint) -1;
2566
2598
  if (error == HA_ERR_FOUND_DUPP_KEY || error == HA_ERR_FOREIGN_DUPLICATE_KEY ||
2634
2666
/**
2635
2667
  Performs checks upon the table.
2636
2668
 
2637
 
  @param session                thread doing CHECK Table operation
 
2669
  @param thd                thread doing CHECK Table operation
2638
2670
  @param check_opt          options from the parser
2639
2671
 
2640
2672
  @retval
2646
2678
  @retval
2647
2679
    HA_ADMIN_NOT_IMPLEMENTED
2648
2680
*/
2649
 
int handler::ha_check(Session *session, HA_CHECK_OPT *check_opt)
 
2681
int handler::ha_check(THD *thd, HA_CHECK_OPT *check_opt)
2650
2682
{
2651
2683
  int error;
2652
2684
 
2664
2696
    if (!error && (check_opt->sql_flags & TT_FOR_UPGRADE))
2665
2697
      return 0;
2666
2698
  }
2667
 
  if ((error= check(session, check_opt)))
 
2699
  if ((error= check(thd, check_opt)))
2668
2700
    return error;
2669
2701
  return update_frm_version(table);
2670
2702
}
2678
2710
void
2679
2711
handler::mark_trx_read_write()
2680
2712
{
2681
 
  Ha_trx_info *ha_info= &ha_session()->ha_data[ht->slot].ha_info[0];
 
2713
  Ha_trx_info *ha_info= &ha_thd()->ha_data[ht->slot].ha_info[0];
2682
2714
  /*
2683
2715
    When a storage engine method is called, the transaction must
2684
2716
    have been started, unless it's a DDL call, for which the
2706
2738
  @sa handler::repair()
2707
2739
*/
2708
2740
 
2709
 
int handler::ha_repair(Session* session, HA_CHECK_OPT* check_opt)
 
2741
int handler::ha_repair(THD* thd, HA_CHECK_OPT* check_opt)
2710
2742
{
2711
2743
  int result;
2712
2744
 
2713
2745
  mark_trx_read_write();
2714
2746
 
2715
 
  if ((result= repair(session, check_opt)))
 
2747
  if ((result= repair(thd, check_opt)))
2716
2748
    return result;
2717
2749
  return update_frm_version(table);
2718
2750
}
2725
2757
*/
2726
2758
 
2727
2759
int
2728
 
handler::ha_bulk_update_row(const unsigned char *old_data, unsigned char *new_data,
2729
 
                            uint32_t *dup_key_found)
 
2760
handler::ha_bulk_update_row(const uchar *old_data, uchar *new_data,
 
2761
                            uint *dup_key_found)
2730
2762
{
2731
2763
  mark_trx_read_write();
2732
2764
 
2771
2803
*/
2772
2804
 
2773
2805
int
2774
 
handler::ha_optimize(Session* session, HA_CHECK_OPT* check_opt)
 
2806
handler::ha_optimize(THD* thd, HA_CHECK_OPT* check_opt)
2775
2807
{
2776
2808
  mark_trx_read_write();
2777
2809
 
2778
 
  return optimize(session, check_opt);
 
2810
  return optimize(thd, check_opt);
2779
2811
}
2780
2812
 
2781
2813
 
2786
2818
*/
2787
2819
 
2788
2820
int
2789
 
handler::ha_analyze(Session* session, HA_CHECK_OPT* check_opt)
 
2821
handler::ha_analyze(THD* thd, HA_CHECK_OPT* check_opt)
2790
2822
{
2791
2823
  mark_trx_read_write();
2792
2824
 
2793
 
  return analyze(session, check_opt);
 
2825
  return analyze(thd, check_opt);
2794
2826
}
2795
2827
 
2796
2828
 
2801
2833
*/
2802
2834
 
2803
2835
bool
2804
 
handler::ha_check_and_repair(Session *session)
 
2836
handler::ha_check_and_repair(THD *thd)
2805
2837
{
2806
2838
  mark_trx_read_write();
2807
2839
 
2808
 
  return check_and_repair(session);
 
2840
  return check_and_repair(thd);
2809
2841
}
2810
2842
 
2811
2843
 
2816
2848
*/
2817
2849
 
2818
2850
int
2819
 
handler::ha_disable_indexes(uint32_t mode)
 
2851
handler::ha_disable_indexes(uint mode)
2820
2852
{
2821
2853
  mark_trx_read_write();
2822
2854
 
2831
2863
*/
2832
2864
 
2833
2865
int
2834
 
handler::ha_enable_indexes(uint32_t mode)
 
2866
handler::ha_enable_indexes(uint mode)
2835
2867
{
2836
2868
  mark_trx_read_write();
2837
2869
 
2955
2987
  starts to commit every now and then automatically.
2956
2988
  This hint can be safely ignored.
2957
2989
*/
2958
 
int ha_enable_transaction(Session *session, bool on)
 
2990
int ha_enable_transaction(THD *thd, bool on)
2959
2991
{
2960
2992
  int error=0;
2961
2993
 
2962
 
  if ((session->transaction.on= on))
 
2994
  if ((thd->transaction.on= on))
2963
2995
  {
2964
2996
    /*
2965
2997
      Now all storage engines should have transaction handling enabled.
2967
2999
      is an optimization hint that storage engine is free to ignore.
2968
3000
      So, let's commit an open transaction (if any) now.
2969
3001
    */
2970
 
    if (!(error= ha_commit_trans(session, 0)))
2971
 
      error= end_trans(session, COMMIT);
 
3002
    if (!(error= ha_commit_trans(thd, 0)))
 
3003
      error= end_trans(thd, COMMIT);
2972
3004
  }
2973
3005
  return(error);
2974
3006
}
2975
3007
 
2976
 
int handler::index_next_same(unsigned char *buf, const unsigned char *key, uint32_t keylen)
 
3008
int handler::index_next_same(uchar *buf, const uchar *key, uint keylen)
2977
3009
{
2978
3010
  int error;
2979
3011
  if (!(error=index_next(buf)))
2980
3012
  {
2981
3013
    my_ptrdiff_t ptrdiff= buf - table->record[0];
2982
 
    unsigned char *save_record_0= NULL;
 
3014
    uchar *save_record_0= NULL;
2983
3015
    KEY *key_info= NULL;
2984
3016
    KEY_PART_INFO *key_part;
2985
3017
    KEY_PART_INFO *key_part_end= NULL;
3036
3068
  @retval
3037
3069
   1  error
3038
3070
*/
3039
 
int ha_create_table(Session *session, const char *path,
 
3071
int ha_create_table(THD *thd, const char *path,
3040
3072
                    const char *db, const char *table_name,
3041
3073
                    HA_CREATE_INFO *create_info,
3042
3074
                    bool update_create_info)
3047
3079
  const char *name;
3048
3080
  TABLE_SHARE share;
3049
3081
  
3050
 
  init_tmp_table_share(session, &share, db, 0, table_name, path);
3051
 
  if (open_table_def(session, &share, 0) ||
3052
 
      open_table_from_share(session, &share, "", 0, (uint) READ_ALL, 0, &table,
 
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,
3053
3085
                            OTM_CREATE))
3054
3086
    goto err;
3055
3087
 
3059
3091
  name= check_lowercase_names(table.file, share.path.str, name_buff);
3060
3092
 
3061
3093
  error= table.file->ha_create(name, &table, create_info);
3062
 
  closefrm(&table, 0);
 
3094
  VOID(closefrm(&table, 0));
3063
3095
  if (error)
3064
3096
  {
3065
 
    strxmov(name_buff, db, ".", table_name, NULL);
 
3097
    strxmov(name_buff, db, ".", table_name, NullS);
3066
3098
    my_error(ER_CANT_CREATE_TABLE, MYF(ME_BELL+ME_WAITTANG), name_buff, error);
3067
3099
  }
3068
3100
err:
3083
3115
  @retval
3084
3116
   > 0  Error, table existed but could not be created
3085
3117
*/
3086
 
int ha_create_table_from_engine(Session* session, const char *db, const char *name)
 
3118
int ha_create_table_from_engine(THD* thd, const char *db, const char *name)
3087
3119
{
3088
3120
  int error;
3089
 
  unsigned char *frmblob;
 
3121
  uchar *frmblob;
3090
3122
  size_t frmlen;
3091
3123
  char path[FN_REFLEN];
3092
3124
  HA_CREATE_INFO create_info;
3094
3126
  TABLE_SHARE share;
3095
3127
 
3096
3128
  memset(&create_info, 0, sizeof(create_info));
3097
 
  if ((error= ha_discover(session, db, name, &frmblob, &frmlen)))
 
3129
  if ((error= ha_discover(thd, db, name, &frmblob, &frmlen)))
3098
3130
  {
3099
3131
    /* Table could not be discovered and thus not created */
3100
3132
    return(error);
3108
3140
  build_table_filename(path, FN_REFLEN-1, db, name, "", 0);
3109
3141
  // Save the frm file
3110
3142
  error= writefrm(path, frmblob, frmlen);
3111
 
  free(frmblob);
 
3143
  my_free(frmblob, MYF(0));
3112
3144
  if (error)
3113
3145
    return(2);
3114
3146
 
3115
 
  init_tmp_table_share(session, &share, db, 0, name, path);
3116
 
  if (open_table_def(session, &share, 0))
 
3147
  init_tmp_table_share(thd, &share, db, 0, name, path);
 
3148
  if (open_table_def(thd, &share, 0))
3117
3149
  {
3118
3150
    return(3);
3119
3151
  }
3120
 
  if (open_table_from_share(session, &share, "" ,0, 0, 0, &table, OTM_OPEN))
 
3152
  if (open_table_from_share(thd, &share, "" ,0, 0, 0, &table, OTM_OPEN))
3121
3153
  {
3122
3154
    free_table_share(&share);
3123
3155
    return(3);
3128
3160
 
3129
3161
  check_lowercase_names(table.file, path, path);
3130
3162
  error=table.file->ha_create(path, &table, &create_info);
3131
 
  closefrm(&table, 1);
 
3163
  VOID(closefrm(&table, 1));
3132
3164
 
3133
3165
  return(error != 0);
3134
3166
}
3136
3168
void st_ha_check_opt::init()
3137
3169
{
3138
3170
  flags= sql_flags= 0;
3139
 
  sort_buffer_size = current_session->variables.myisam_sort_buff_size;
 
3171
  sort_buffer_size = current_thd->variables.myisam_sort_buff_size;
3140
3172
}
3141
3173
 
3142
3174
 
3160
3192
  {
3161
3193
    pthread_mutex_lock(&LOCK_global_system_variables);
3162
3194
    uint32_t tmp_buff_size= (uint32_t) key_cache->param_buff_size;
3163
 
    uint32_t tmp_block_size= (uint) key_cache->param_block_size;
3164
 
    uint32_t division_limit= key_cache->param_division_limit;
3165
 
    uint32_t age_threshold=  key_cache->param_age_threshold;
 
3195
    uint tmp_block_size= (uint) key_cache->param_block_size;
 
3196
    uint division_limit= key_cache->param_division_limit;
 
3197
    uint age_threshold=  key_cache->param_age_threshold;
3166
3198
    pthread_mutex_unlock(&LOCK_global_system_variables);
3167
3199
    return(!init_key_cache(key_cache,
3168
3200
                                tmp_block_size,
3183
3215
    pthread_mutex_lock(&LOCK_global_system_variables);
3184
3216
    long tmp_buff_size= (long) key_cache->param_buff_size;
3185
3217
    long tmp_block_size= (long) key_cache->param_block_size;
3186
 
    uint32_t division_limit= key_cache->param_division_limit;
3187
 
    uint32_t age_threshold=  key_cache->param_age_threshold;
 
3218
    uint division_limit= key_cache->param_division_limit;
 
3219
    uint age_threshold=  key_cache->param_age_threshold;
3188
3220
    pthread_mutex_unlock(&LOCK_global_system_variables);
3189
3221
    return(!resize_key_cache(key_cache, tmp_block_size,
3190
3222
                                  tmp_buff_size,
3202
3234
  if (key_cache->key_cache_inited)
3203
3235
  {
3204
3236
    pthread_mutex_lock(&LOCK_global_system_variables);
3205
 
    uint32_t division_limit= key_cache->param_division_limit;
3206
 
    uint32_t age_threshold=  key_cache->param_age_threshold;
 
3237
    uint division_limit= key_cache->param_division_limit;
 
3238
    uint age_threshold=  key_cache->param_age_threshold;
3207
3239
    pthread_mutex_unlock(&LOCK_global_system_variables);
3208
3240
    change_key_cache_param(key_cache, division_limit, age_threshold);
3209
3241
  }
3244
3276
{
3245
3277
  const char *db;
3246
3278
  const char *name;
3247
 
  unsigned char **frmblob; 
 
3279
  uchar **frmblob; 
3248
3280
  size_t *frmlen;
3249
3281
};
3250
3282
 
3251
 
static bool discover_handlerton(Session *session, plugin_ref plugin,
 
3283
static bool discover_handlerton(THD *thd, plugin_ref plugin,
3252
3284
                                void *arg)
3253
3285
{
3254
3286
  st_discover_args *vargs= (st_discover_args *)arg;
3255
3287
  handlerton *hton= plugin_data(plugin, handlerton *);
3256
3288
  if (hton->state == SHOW_OPTION_YES && hton->discover &&
3257
 
      (!(hton->discover(hton, session, vargs->db, vargs->name, 
 
3289
      (!(hton->discover(hton, thd, vargs->db, vargs->name, 
3258
3290
                        vargs->frmblob, 
3259
3291
                        vargs->frmlen))))
3260
3292
    return true;
3262
3294
  return false;
3263
3295
}
3264
3296
 
3265
 
int ha_discover(Session *session, const char *db, const char *name,
3266
 
                unsigned char **frmblob, size_t *frmlen)
 
3297
int ha_discover(THD *thd, const char *db, const char *name,
 
3298
                uchar **frmblob, size_t *frmlen)
3267
3299
{
3268
3300
  int error= -1; // Table does not exist in any handler
3269
3301
  st_discover_args args= {db, name, frmblob, frmlen};
3271
3303
  if (is_prefix(name,tmp_file_prefix)) /* skip temporary tables */
3272
3304
    return(error);
3273
3305
 
3274
 
  if (plugin_foreach(session, discover_handlerton,
 
3306
  if (plugin_foreach(thd, discover_handlerton,
3275
3307
                 DRIZZLE_STORAGE_ENGINE_PLUGIN, &args))
3276
3308
    error= 0;
3277
3309
 
3278
3310
  if (!error)
3279
 
    status_var_increment(session->status_var.ha_discover_count);
 
3311
    status_var_increment(thd->status_var.ha_discover_count);
3280
3312
  return(error);
3281
3313
}
3282
3314
 
3311
3343
  int err;
3312
3344
};
3313
3345
 
3314
 
static bool table_exists_in_engine_handlerton(Session *session, plugin_ref plugin,
 
3346
static bool table_exists_in_engine_handlerton(THD *thd, plugin_ref plugin,
3315
3347
                                              void *arg)
3316
3348
{
3317
3349
  st_table_exists_in_engine_args *vargs= (st_table_exists_in_engine_args *)arg;
3320
3352
  int err= HA_ERR_NO_SUCH_TABLE;
3321
3353
 
3322
3354
  if (hton->state == SHOW_OPTION_YES && hton->table_exists_in_engine)
3323
 
    err = hton->table_exists_in_engine(hton, session, vargs->db, vargs->name);
 
3355
    err = hton->table_exists_in_engine(hton, thd, vargs->db, vargs->name);
3324
3356
 
3325
3357
  vargs->err = err;
3326
3358
  if (vargs->err == HA_ERR_TABLE_EXIST)
3329
3361
  return false;
3330
3362
}
3331
3363
 
3332
 
int ha_table_exists_in_engine(Session* session, const char* db, const char* name)
 
3364
int ha_table_exists_in_engine(THD* thd, const char* db, const char* name)
3333
3365
{
3334
3366
  st_table_exists_in_engine_args args= {db, name, HA_ERR_NO_SUCH_TABLE};
3335
 
  plugin_foreach(session, table_exists_in_engine_handlerton,
 
3367
  plugin_foreach(thd, table_exists_in_engine_handlerton,
3336
3368
                 DRIZZLE_STORAGE_ENGINE_PLUGIN, &args);
3337
3369
  return(args.err);
3338
3370
}
3358
3390
    Estimated cost of 'index only' scan
3359
3391
*/
3360
3392
 
3361
 
double handler::index_only_read_time(uint32_t keynr, double records)
 
3393
double handler::index_only_read_time(uint keynr, double records)
3362
3394
{
3363
3395
  double read_time;
3364
 
  uint32_t keys_per_block= (stats.block_size/2/
 
3396
  uint keys_per_block= (stats.block_size/2/
3365
3397
                        (table->key_info[keynr].key_length + ref_length) + 1);
3366
3398
  read_time=((double) (records + keys_per_block-1) /
3367
3399
             (double) keys_per_block);
3392
3424
 
3393
3425
  @note
3394
3426
    This method (or an overriding one in a derived class) must check for
3395
 
    session->killed and return HA_POS_ERROR if it is not zero. This is required
 
3427
    thd->killed and return HA_POS_ERROR if it is not zero. This is required
3396
3428
    for a user to be able to interrupt the calculation by killing the
3397
3429
    connection/query.
3398
3430
 
3405
3437
*/
3406
3438
 
3407
3439
ha_rows
3408
 
handler::multi_range_read_info_const(uint32_t keyno, RANGE_SEQ_IF *seq,
 
3440
handler::multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq,
3409
3441
                                     void *seq_init_param,
3410
 
                                     uint32_t n_ranges_arg __attribute__((unused)),
3411
 
                                     uint32_t *bufsz, uint32_t *flags, COST_VECT *cost)
 
3442
                                     uint n_ranges_arg __attribute__((unused)),
 
3443
                                     uint *bufsz, uint *flags, COST_VECT *cost)
3412
3444
{
3413
3445
  KEY_MULTI_RANGE range;
3414
3446
  range_seq_t seq_it;
3415
3447
  ha_rows rows, total_rows= 0;
3416
 
  uint32_t n_ranges=0;
3417
 
  Session *session= current_session;
 
3448
  uint n_ranges=0;
 
3449
  THD *thd= current_thd;
3418
3450
  
3419
3451
  /* Default MRR implementation doesn't need buffer */
3420
3452
  *bufsz= 0;
3422
3454
  seq_it= seq->init(seq_init_param, n_ranges, *flags);
3423
3455
  while (!seq->next(seq_it, &range))
3424
3456
  {
3425
 
    if (unlikely(session->killed != 0))
 
3457
    if (unlikely(thd->killed != 0))
3426
3458
      return HA_POS_ERROR;
3427
3459
    
3428
3460
    n_ranges++;
3496
3528
    other Error or can't perform the requested scan
3497
3529
*/
3498
3530
 
3499
 
int handler::multi_range_read_info(uint32_t keyno, uint32_t n_ranges, uint32_t n_rows,
3500
 
                                   uint32_t *bufsz, uint32_t *flags, COST_VECT *cost)
 
3531
int handler::multi_range_read_info(uint keyno, uint n_ranges, uint n_rows,
 
3532
                                   uint *bufsz, uint *flags, COST_VECT *cost)
3501
3533
{
3502
3534
  *bufsz= 0; /* Default implementation doesn't need a buffer */
3503
3535
 
3558
3590
 
3559
3591
int
3560
3592
handler::multi_range_read_init(RANGE_SEQ_IF *seq_funcs, void *seq_init_param,
3561
 
                               uint32_t n_ranges, uint32_t mode,
 
3593
                               uint n_ranges, uint mode,
3562
3594
                               HANDLER_BUFFER *buf __attribute__((unused)))
3563
3595
{
3564
3596
  mrr_iter= seq_funcs->init(seq_init_param, n_ranges, mode);
3660
3692
 
3661
3693
int DsMrr_impl::dsmrr_init(handler *h, KEY *key,
3662
3694
                           RANGE_SEQ_IF *seq_funcs, void *seq_init_param,
3663
 
                           uint32_t n_ranges, uint32_t mode, HANDLER_BUFFER *buf)
 
3695
                           uint n_ranges, uint mode, HANDLER_BUFFER *buf)
3664
3696
{
3665
 
  uint32_t elem_size;
3666
 
  uint32_t keyno;
 
3697
  uint elem_size;
 
3698
  uint keyno;
3667
3699
  Item *pushed_cond= NULL;
3668
3700
  handler *new_h2;
3669
3701
  keyno= h->active_index;
3688
3720
  rowids_buf_end= rowids_buf_last;
3689
3721
 
3690
3722
  /* Create a separate handler object to do rndpos() calls. */
3691
 
  Session *session= current_session;
3692
 
  if (!(new_h2= h->clone(session->mem_root)) || 
3693
 
      new_h2->ha_external_lock(session, F_RDLCK))
 
3723
  THD *thd= current_thd;
 
3724
  if (!(new_h2= h->clone(thd->mem_root)) || 
 
3725
      new_h2->ha_external_lock(thd, F_RDLCK))
3694
3726
  {
3695
3727
    delete new_h2;
3696
3728
    return(1);
3732
3764
  return(0);
3733
3765
error:
3734
3766
  h2->ha_index_or_rnd_end();
3735
 
  h2->ha_external_lock(session, F_UNLCK);
 
3767
  h2->ha_external_lock(thd, F_UNLCK);
3736
3768
  h2->close();
3737
3769
  delete h2;
3738
3770
  return(1);
3743
3775
{
3744
3776
  if (h2)
3745
3777
  {
3746
 
    h2->ha_external_lock(current_session, F_UNLCK);
 
3778
    h2->ha_external_lock(current_thd, F_UNLCK);
3747
3779
    h2->close();
3748
3780
    delete h2;
3749
3781
    h2= NULL;
3753
3785
}
3754
3786
 
3755
3787
 
3756
 
static int rowid_cmp(void *h, unsigned char *a, unsigned char *b)
 
3788
static int rowid_cmp(void *h, uchar *a, uchar *b)
3757
3789
{
3758
3790
  return ((handler*)h)->cmp_ref(a, b);
3759
3791
}
3802
3834
  dsmrr_eof= test(res == HA_ERR_END_OF_FILE);
3803
3835
 
3804
3836
  /* Sort the buffer contents by rowid */
3805
 
  uint32_t elem_size= h->ref_length + (int)is_mrr_assoc * sizeof(void*);
3806
 
  uint32_t n_rowids= (rowids_buf_cur - rowids_buf) / elem_size;
 
3837
  uint elem_size= h->ref_length + (int)is_mrr_assoc * sizeof(void*);
 
3838
  uint n_rowids= (rowids_buf_cur - rowids_buf) / elem_size;
3807
3839
  
3808
3840
  my_qsort2(rowids_buf, n_rowids, elem_size, (qsort2_cmp)rowid_cmp,
3809
3841
            (void*)h);
3861
3893
/**
3862
3894
  DS-MRR implementation: multi_range_read_info() function
3863
3895
*/
3864
 
int DsMrr_impl::dsmrr_info(uint32_t keyno, uint32_t n_ranges, uint32_t rows, uint32_t *bufsz,
3865
 
                           uint32_t *flags, COST_VECT *cost)
 
3896
int DsMrr_impl::dsmrr_info(uint keyno, uint n_ranges, uint rows, uint *bufsz,
 
3897
                           uint *flags, COST_VECT *cost)
3866
3898
{  
3867
3899
  int res;
3868
 
  uint32_t def_flags= *flags;
3869
 
  uint32_t def_bufsz= *bufsz;
 
3900
  uint def_flags= *flags;
 
3901
  uint def_bufsz= *bufsz;
3870
3902
 
3871
3903
  /* Get cost/flags/mem_usage of default MRR implementation */
3872
3904
  res= h->handler::multi_range_read_info(keyno, n_ranges, rows, &def_bufsz,
3888
3920
  DS-MRR Implementation: multi_range_read_info_const() function
3889
3921
*/
3890
3922
 
3891
 
ha_rows DsMrr_impl::dsmrr_info_const(uint32_t keyno, RANGE_SEQ_IF *seq,
3892
 
                                 void *seq_init_param, uint32_t n_ranges, 
3893
 
                                 uint32_t *bufsz, uint32_t *flags, COST_VECT *cost)
 
3923
ha_rows DsMrr_impl::dsmrr_info_const(uint keyno, RANGE_SEQ_IF *seq,
 
3924
                                 void *seq_init_param, uint n_ranges, 
 
3925
                                 uint *bufsz, uint *flags, COST_VECT *cost)
3894
3926
{
3895
3927
  ha_rows rows;
3896
 
  uint32_t def_flags= *flags;
3897
 
  uint32_t def_bufsz= *bufsz;
 
3928
  uint def_flags= *flags;
 
3929
  uint def_bufsz= *bufsz;
3898
3930
  /* Get cost/flags/mem_usage of default MRR implementation */
3899
3931
  rows= h->handler::multi_range_read_info_const(keyno, seq, seq_init_param,
3900
3932
                                                n_ranges, &def_bufsz, 
3942
3974
  @retval false  No
3943
3975
*/
3944
3976
 
3945
 
bool DsMrr_impl::key_uses_partial_cols(uint32_t keyno)
 
3977
bool DsMrr_impl::key_uses_partial_cols(uint keyno)
3946
3978
{
3947
3979
  KEY_PART_INFO *kp= table->key_info[keyno].key_part;
3948
3980
  KEY_PART_INFO *kp_end= kp + table->key_info[keyno].key_parts;
3978
4010
  @retval false  DS-MRR implementation should be used
3979
4011
*/
3980
4012
 
3981
 
bool DsMrr_impl::choose_mrr_impl(uint32_t keyno, ha_rows rows, uint32_t *flags,
3982
 
                                 uint32_t *bufsz, COST_VECT *cost)
 
4013
bool DsMrr_impl::choose_mrr_impl(uint keyno, ha_rows rows, uint *flags,
 
4014
                                 uint *bufsz, COST_VECT *cost)
3983
4015
{
3984
4016
  COST_VECT dsmrr_cost;
3985
4017
  bool res;
3986
 
  Session *session= current_session;
3987
 
  if ((session->variables.optimizer_use_mrr == 2) || 
 
4018
  THD *thd= current_thd;
 
4019
  if ((thd->variables.optimizer_use_mrr == 2) || 
3988
4020
      (*flags & HA_MRR_INDEX_ONLY) || (*flags & HA_MRR_SORTED) ||
3989
4021
      (keyno == table->s->primary_key && 
3990
4022
       h->primary_key_is_clustered()) || 
3995
4027
    return true;
3996
4028
  }
3997
4029
  
3998
 
  uint32_t add_len= table->key_info[keyno].key_length + h->ref_length; 
 
4030
  uint add_len= table->key_info[keyno].key_length + h->ref_length; 
3999
4031
  *bufsz -= add_len;
4000
4032
  if (get_disk_sweep_mrr_cost(keyno, rows, *flags, bufsz, &dsmrr_cost))
4001
4033
    return true;
4008
4040
    DS-MRR whenever it is applicable without affecting other cost-based
4009
4041
    choices.
4010
4042
  */
4011
 
  if ((force_dsmrr= (session->variables.optimizer_use_mrr == 1)) &&
 
4043
  if ((force_dsmrr= (thd->variables.optimizer_use_mrr == 1)) &&
4012
4044
      dsmrr_cost.total_cost() > cost->total_cost())
4013
4045
    dsmrr_cost= *cost;
4014
4046
 
4045
4077
                 for even 1 rowid)
4046
4078
*/
4047
4079
 
4048
 
bool DsMrr_impl::get_disk_sweep_mrr_cost(uint32_t keynr, ha_rows rows, uint32_t flags,
4049
 
                                         uint32_t *buffer_size, COST_VECT *cost)
 
4080
bool DsMrr_impl::get_disk_sweep_mrr_cost(uint keynr, ha_rows rows, uint flags,
 
4081
                                         uint *buffer_size, COST_VECT *cost)
4050
4082
{
4051
4083
  uint32_t max_buff_entries, elem_size;
4052
4084
  ha_rows rows_in_full_step, rows_in_last_step;
4053
 
  uint32_t n_full_steps;
 
4085
  uint n_full_steps;
4054
4086
  double index_read_cost;
4055
4087
 
4056
4088
  elem_size= h->ref_length + sizeof(void*) * (!test(flags & HA_MRR_NO_ASSOCIATION));
4079
4111
  else
4080
4112
  {
4081
4113
    cost->zero();
4082
 
    *buffer_size= cmax((ulong)*buffer_size, 
 
4114
    *buffer_size= max((ulong)*buffer_size, 
4083
4115
                      (size_t)(1.2*rows_in_last_step) * elem_size + 
4084
4116
                      h->ref_length + table->key_info[keynr].key_length);
4085
4117
  }
4336
4368
  return cmp;
4337
4369
}
4338
4370
 
4339
 
int handler::index_read_idx_map(unsigned char * buf, uint32_t index, const unsigned char * key,
 
4371
int handler::index_read_idx_map(uchar * buf, uint index, const uchar * key,
4340
4372
                                key_part_map keypart_map,
4341
4373
                                enum ha_rkey_function find_flag)
4342
4374
{
4361
4393
  @retval
4362
4394
    pointer             pointer to TYPELIB structure
4363
4395
*/
4364
 
static bool exts_handlerton(Session *unused __attribute__((unused)),
 
4396
static bool exts_handlerton(THD *unused __attribute__((unused)),
4365
4397
                            plugin_ref plugin,
4366
4398
                            void *arg)
4367
4399
{
4369
4401
  handlerton *hton= plugin_data(plugin, handlerton *);
4370
4402
  handler *file;
4371
4403
  if (hton->state == SHOW_OPTION_YES && hton->create &&
4372
 
      (file= hton->create(hton, (TABLE_SHARE*) 0, current_session->mem_root)))
 
4404
      (file= hton->create(hton, (TABLE_SHARE*) 0, current_thd->mem_root)))
4373
4405
  {
4374
4406
    List_iterator_fast<char> it(*found_exts);
4375
4407
    const char **ext, *old_ext;
4420
4452
}
4421
4453
 
4422
4454
 
4423
 
static bool stat_print(Session *session, const char *type, uint32_t type_len,
4424
 
                       const char *file, uint32_t file_len,
4425
 
                       const char *status, uint32_t status_len)
 
4455
static bool stat_print(THD *thd, const char *type, uint type_len,
 
4456
                       const char *file, uint file_len,
 
4457
                       const char *status, uint status_len)
4426
4458
{
4427
 
  Protocol *protocol= session->protocol;
 
4459
  Protocol *protocol= thd->protocol;
4428
4460
  protocol->prepare_for_resend();
4429
4461
  protocol->store(type, type_len, system_charset_info);
4430
4462
  protocol->store(file, file_len, system_charset_info);
4434
4466
  return false;
4435
4467
}
4436
4468
 
4437
 
bool ha_show_status(Session *session, handlerton *db_type, enum ha_stat_type stat)
 
4469
bool ha_show_status(THD *thd, handlerton *db_type, enum ha_stat_type stat)
4438
4470
{
4439
4471
  List<Item> field_list;
4440
 
  Protocol *protocol= session->protocol;
 
4472
  Protocol *protocol= thd->protocol;
4441
4473
  bool result;
4442
4474
 
4443
4475
  field_list.push_back(new Item_empty_string("Type",10));
4449
4481
    return true;
4450
4482
 
4451
4483
  result= db_type->show_status &&
4452
 
    db_type->show_status(db_type, session, stat_print, stat) ? 1 : 0;
 
4484
    db_type->show_status(db_type, thd, stat_print, stat) ? 1 : 0;
4453
4485
 
4454
4486
  if (!result)
4455
 
    my_eof(session);
 
4487
    my_eof(thd);
4456
4488
  return result;
4457
4489
}
4458
4490
 
4469
4501
  - table is not mysql.event
4470
4502
*/
4471
4503
 
4472
 
static bool check_table_binlog_row_based(Session *session, Table *table)
 
4504
static bool check_table_binlog_row_based(THD *thd, Table *table)
4473
4505
{
4474
4506
  if (table->s->cached_row_logging_check == -1)
4475
4507
  {
4481
4513
  assert(table->s->cached_row_logging_check == 0 ||
4482
4514
              table->s->cached_row_logging_check == 1);
4483
4515
 
4484
 
  return (session->current_stmt_binlog_row_based &&
 
4516
  return (thd->current_stmt_binlog_row_based &&
4485
4517
          table->s->cached_row_logging_check &&
4486
 
          (session->options & OPTION_BIN_LOG) &&
 
4518
          (thd->options & OPTION_BIN_LOG) &&
4487
4519
          mysql_bin_log.is_open());
4488
4520
}
4489
4521
 
4493
4525
   to the binary log.
4494
4526
 
4495
4527
   This function will generate and write table maps for all tables
4496
 
   that are locked by the thread 'session'.  Either manually locked
4497
 
   (stored in Session::locked_tables) and automatically locked (stored
4498
 
   in Session::lock) are considered.
 
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.
4499
4531
 
4500
 
   @param session     Pointer to Session structure
 
4532
   @param thd     Pointer to THD structure
4501
4533
 
4502
4534
   @retval 0   All OK
4503
4535
   @retval 1   Failed to write all table maps
4504
4536
 
4505
4537
   @sa
4506
 
       Session::lock
4507
 
       Session::locked_tables
 
4538
       THD::lock
 
4539
       THD::locked_tables
4508
4540
*/
4509
4541
 
4510
 
static int write_locked_table_maps(Session *session)
 
4542
static int write_locked_table_maps(THD *thd)
4511
4543
{
4512
 
  if (session->get_binlog_table_maps() == 0)
 
4544
  if (thd->get_binlog_table_maps() == 0)
4513
4545
  {
4514
4546
    DRIZZLE_LOCK *locks[3];
4515
 
    locks[0]= session->extra_lock;
4516
 
    locks[1]= session->lock;
4517
 
    locks[2]= session->locked_tables;
4518
 
    for (uint32_t i= 0 ; i < sizeof(locks)/sizeof(*locks) ; ++i )
 
4547
    locks[0]= thd->extra_lock;
 
4548
    locks[1]= thd->lock;
 
4549
    locks[2]= thd->locked_tables;
 
4550
    for (uint i= 0 ; i < sizeof(locks)/sizeof(*locks) ; ++i )
4519
4551
    {
4520
4552
      DRIZZLE_LOCK const *const lock= locks[i];
4521
4553
      if (lock == NULL)
4528
4560
      {
4529
4561
        Table *const table= *table_ptr;
4530
4562
        if (table->current_lock == F_WRLCK &&
4531
 
            check_table_binlog_row_based(session, table))
 
4563
            check_table_binlog_row_based(thd, table))
4532
4564
        {
4533
4565
          int const has_trans= table->file->has_transactions();
4534
 
          int const error= session->binlog_write_table_map(table, has_trans);
 
4566
          int const error= thd->binlog_write_table_map(table, has_trans);
4535
4567
          /*
4536
4568
            If an error occurs, it is the responsibility of the caller to
4537
4569
            roll back the transaction.
4546
4578
}
4547
4579
 
4548
4580
 
4549
 
typedef bool Log_func(Session*, Table*, bool, const unsigned char*, const unsigned char*);
 
4581
typedef bool Log_func(THD*, Table*, bool, const uchar*, const uchar*);
4550
4582
 
4551
4583
static int binlog_log_row(Table* table,
4552
 
                          const unsigned char *before_record,
4553
 
                          const unsigned char *after_record,
 
4584
                          const uchar *before_record,
 
4585
                          const uchar *after_record,
4554
4586
                          Log_func *log_func)
4555
4587
{
4556
4588
  if (table->no_replicate)
4557
4589
    return 0;
4558
4590
  bool error= 0;
4559
 
  Session *const session= table->in_use;
 
4591
  THD *const thd= table->in_use;
4560
4592
 
4561
 
  if (check_table_binlog_row_based(session, table))
 
4593
  if (check_table_binlog_row_based(thd, table))
4562
4594
  {
4563
4595
    /*
4564
4596
      If there are no table maps written to the binary log, this is
4565
4597
      the first row handled in this statement. In that case, we need
4566
4598
      to write table maps for all locked tables to the binary log.
4567
4599
    */
4568
 
    if (likely(!(error= write_locked_table_maps(session))))
 
4600
    if (likely(!(error= write_locked_table_maps(thd))))
4569
4601
    {
4570
4602
      bool const has_trans= table->file->has_transactions();
4571
 
      error= (*log_func)(session, table, has_trans, before_record, after_record);
 
4603
      error= (*log_func)(thd, table, has_trans, before_record, after_record);
4572
4604
    }
4573
4605
  }
4574
4606
  return error ? HA_ERR_RBR_LOGGING_FAILED : 0;
4575
4607
}
4576
4608
 
4577
 
int handler::ha_external_lock(Session *session, int lock_type)
 
4609
int handler::ha_external_lock(THD *thd, int lock_type)
4578
4610
{
4579
4611
  /*
4580
4612
    Whether this is lock or unlock, this should be true, and is to verify that
4589
4621
  */
4590
4622
  DRIZZLE_EXTERNAL_LOCK(lock_type);
4591
4623
 
4592
 
  int error= external_lock(session, lock_type);
 
4624
  int error= external_lock(thd, lock_type);
4593
4625
  if (error == 0)
4594
4626
    cached_table_flags= table_flags();
4595
4627
  return(error);
4602
4634
int handler::ha_reset()
4603
4635
{
4604
4636
  /* Check that we have called all proper deallocation functions */
4605
 
  assert((unsigned char*) table->def_read_set.bitmap +
 
4637
  assert((uchar*) table->def_read_set.bitmap +
4606
4638
              table->s->column_bitmap_size ==
4607
 
              (unsigned char*) table->def_write_set.bitmap);
 
4639
              (uchar*) table->def_write_set.bitmap);
4608
4640
  assert(bitmap_is_set_all(&table->s->all_set));
4609
4641
  assert(table->key_read == 0);
4610
4642
  /* ensure that ha_index_end / ha_rnd_end has been called */
4617
4649
}
4618
4650
 
4619
4651
 
4620
 
int handler::ha_write_row(unsigned char *buf)
 
4652
int handler::ha_write_row(uchar *buf)
4621
4653
{
4622
4654
  int error;
4623
4655
  Log_func *log_func= Write_rows_log_event::binlog_row_logging_function;
4634
4666
}
4635
4667
 
4636
4668
 
4637
 
int handler::ha_update_row(const unsigned char *old_data, unsigned char *new_data)
 
4669
int handler::ha_update_row(const uchar *old_data, uchar *new_data)
4638
4670
{
4639
4671
  int error;
4640
4672
  Log_func *log_func= Update_rows_log_event::binlog_row_logging_function;
4654
4686
  return 0;
4655
4687
}
4656
4688
 
4657
 
int handler::ha_delete_row(const unsigned char *buf)
 
4689
int handler::ha_delete_row(const uchar *buf)
4658
4690
{
4659
4691
  int error;
4660
4692
  Log_func *log_func= Delete_rows_log_event::binlog_row_logging_function;
4681
4713
  /* fallback to use all columns in the table to identify row */
4682
4714
  table->use_all_columns();
4683
4715
}
4684
 
 
4685
 
void table_case_convert(char * name, uint32_t length)
4686
 
{
4687
 
  if (lower_case_table_names)
4688
 
    files_charset_info->cset->casedn(files_charset_info,
4689
 
                                     name, length, name, length);
4690
 
}
4691
 
 
4692
 
const char *table_case_name(HA_CREATE_INFO *info, const char *name)
4693
 
{
4694
 
  return ((lower_case_table_names == 2 && info->alias) ? info->alias : name);
4695
 
}