66
static plugin_ref ha_default_plugin(Session *thd)
66
static plugin_ref ha_default_plugin(Session *session)
68
if (thd->variables.table_plugin)
69
return thd->variables.table_plugin;
70
return my_plugin_lock(thd, &global_system_variables.table_plugin);
68
if (session->variables.table_plugin)
69
return session->variables.table_plugin;
70
return my_plugin_lock(session, &global_system_variables.table_plugin);
75
75
Return the default storage engine handlerton for thread
77
@param ha_default_handlerton(thd)
78
@param thd current thread
77
@param ha_default_handlerton(session)
78
@param session current thread
81
81
pointer to handlerton
83
handlerton *ha_default_handlerton(Session *thd)
83
handlerton *ha_default_handlerton(Session *session)
85
plugin_ref plugin= ha_default_plugin(thd);
85
plugin_ref plugin= ha_default_plugin(session);
87
87
handlerton *hton= plugin_data(plugin, handlerton*);
94
94
Return the storage engine handlerton for the supplied name
96
@param thd current thread
96
@param session current thread
97
97
@param name name of storage engine
100
100
pointer to storage engine plugin handle
102
plugin_ref ha_resolve_by_name(Session *thd, const LEX_STRING *name)
102
plugin_ref ha_resolve_by_name(Session *session, const LEX_STRING *name)
104
104
const LEX_STRING *table_alias;
105
105
plugin_ref plugin;
108
108
/* my_strnncoll is a macro and gcc doesn't do early expansion of macro */
109
if (thd && !my_charset_utf8_general_ci.coll->strnncoll(&my_charset_utf8_general_ci,
109
if (session && !my_charset_utf8_general_ci.coll->strnncoll(&my_charset_utf8_general_ci,
110
110
(const unsigned char *)name->str, name->length,
111
111
(const unsigned char *)STRING_WITH_LEN("DEFAULT"), 0))
112
return ha_default_plugin(thd);
112
return ha_default_plugin(session);
114
if ((plugin= my_plugin_lock_by_name(thd, name, DRIZZLE_STORAGE_ENGINE_PLUGIN)))
114
if ((plugin= my_plugin_lock_by_name(session, name, DRIZZLE_STORAGE_ENGINE_PLUGIN)))
116
116
handlerton *hton= plugin_data(plugin, handlerton *);
117
117
if (!(hton->flags & HTON_NOT_USER_SELECTABLE))
144
plugin_ref ha_lock_engine(Session *thd, handlerton *hton)
144
plugin_ref ha_lock_engine(Session *session, handlerton *hton)
148
148
st_plugin_int **plugin= hton2plugin + hton->slot;
150
return my_plugin_lock(thd, &plugin);
150
return my_plugin_lock(session, &plugin);
156
handlerton *ha_resolve_by_legacy_type(Session *thd, enum legacy_db_type db_type)
156
handlerton *ha_resolve_by_legacy_type(Session *session, enum legacy_db_type db_type)
158
158
plugin_ref plugin;
159
159
switch (db_type) {
160
160
case DB_TYPE_DEFAULT:
161
return ha_default_handlerton(thd);
161
return ha_default_handlerton(session);
163
163
if (db_type > DB_TYPE_UNKNOWN && db_type < DB_TYPE_DEFAULT &&
164
(plugin= ha_lock_engine(thd, installed_htons[db_type])))
164
(plugin= ha_lock_engine(session, installed_htons[db_type])))
165
165
return plugin_data(plugin, handlerton*);
166
166
/* fall through */
167
167
case DB_TYPE_UNKNOWN:
174
174
Use other database handler if databasehandler is not compiled in.
176
handlerton *ha_checktype(Session *thd, enum legacy_db_type database_type,
176
handlerton *ha_checktype(Session *session, enum legacy_db_type database_type,
177
177
bool no_substitute, bool report_error)
179
handlerton *hton= ha_resolve_by_legacy_type(thd, database_type);
179
handlerton *hton= ha_resolve_by_legacy_type(session, database_type);
180
180
if (ha_storage_engine_is_enabled(hton))
209
209
Try the default table type
210
Here the call to current_thd() is ok as we call this function a lot of
210
Here the call to current_session() is ok as we call this function a lot of
211
211
times but we enter this branch very seldom.
213
return(get_new_handler(share, alloc, ha_default_handlerton(current_thd)));
213
return(get_new_handler(share, alloc, ha_default_handlerton(current_session)));
464
static bool closecon_handlerton(Session *thd, plugin_ref plugin,
464
static bool closecon_handlerton(Session *session, plugin_ref plugin,
465
465
void *unused __attribute__((unused)))
467
467
handlerton *hton= plugin_data(plugin, handlerton *);
470
470
be rolled back already
472
472
if (hton->state == SHOW_OPTION_YES && hton->close_connection &&
473
thd_get_ha_data(thd, hton))
474
hton->close_connection(hton, thd);
473
session_get_ha_data(session, hton))
474
hton->close_connection(hton, session);
481
481
don't bother to rollback here, it's done already
483
void ha_close_connection(Session* thd)
483
void ha_close_connection(Session* session)
485
plugin_foreach(thd, closecon_handlerton, DRIZZLE_STORAGE_ENGINE_PLUGIN, 0);
485
plugin_foreach(session, closecon_handlerton, DRIZZLE_STORAGE_ENGINE_PLUGIN, 0);
488
488
/* ========================================================================
589
589
The server stores its transaction-related data in
590
thd->transaction. This structure has two members of type
590
session->transaction. This structure has two members of type
591
591
Session_TRANS. These members correspond to the statement and
592
592
normal transactions respectively:
594
- thd->transaction.stmt contains a list of engines
594
- session->transaction.stmt contains a list of engines
595
595
that are participating in the given statement
596
- thd->transaction.all contains a list of engines that
596
- session->transaction.all contains a list of engines that
597
597
have participated in any of the statement transactions started
598
598
within the context of the normal transaction.
599
599
Each element of the list contains a pointer to the storage
600
600
engine, engine-specific transactional data, and engine-specific
601
601
transaction flags.
603
In autocommit mode thd->transaction.all is empty.
604
Instead, data of thd->transaction.stmt is
603
In autocommit mode session->transaction.all is empty.
604
Instead, data of session->transaction.stmt is
605
605
used to commit/rollback the normal transaction.
607
607
The list of registered engines has a few important properties:
612
612
Transaction life cycle
613
613
----------------------
615
When a new connection is established, thd->transaction
615
When a new connection is established, session->transaction
616
616
members are initialized to an empty state.
617
617
If a statement uses any tables, all affected engines
618
618
are registered in the statement engine list. In
628
628
and emptied again at the next statement's end.
630
630
The normal transaction is committed in a similar way
631
(by going over all engines in thd->transaction.all list)
631
(by going over all engines in session->transaction.all list)
632
632
but at different times:
633
633
- upon COMMIT SQL statement is issued by the user
634
634
- implicitly, by the server, at the beginning of a DDL statement
638
638
- if the user has requested so, by issuing ROLLBACK SQL
640
640
- if one of the storage engines requested a rollback
641
by setting thd->transaction_rollback_request. This may
641
by setting session->transaction_rollback_request. This may
642
642
happen in case, e.g., when the transaction in the engine was
643
643
chosen a victim of the internal deadlock resolution algorithm
644
644
and rolled back internally. When such a situation happens, there
680
680
transactions of other participants.
682
682
After the normal transaction has been committed,
683
thd->transaction.all list is cleared.
683
session->transaction.all list is cleared.
685
685
When a connection is closed, the current normal transaction, if
686
686
any, is rolled back.
744
744
---------------------------------------------------
746
746
DDLs and operations with non-transactional engines
747
do not "register" in thd->transaction lists, and thus do not
747
do not "register" in session->transaction lists, and thus do not
748
748
modify the transaction state. Besides, each DDL in
749
749
MySQL is prefixed with an implicit normal transaction commit
750
750
(a call to end_active_trans()), and thus leaves nothing
791
791
times per transaction.
794
void trans_register_ha(Session *thd, bool all, handlerton *ht_arg)
794
void trans_register_ha(Session *session, bool all, handlerton *ht_arg)
796
796
Session_TRANS *trans;
797
797
Ha_trx_info *ha_info;
801
trans= &thd->transaction.all;
802
thd->server_status|= SERVER_STATUS_IN_TRANS;
801
trans= &session->transaction.all;
802
session->server_status|= SERVER_STATUS_IN_TRANS;
805
trans= &thd->transaction.stmt;
805
trans= &session->transaction.stmt;
807
ha_info= thd->ha_data[ht_arg->slot].ha_info + static_cast<unsigned>(all);
807
ha_info= session->ha_data[ht_arg->slot].ha_info + static_cast<unsigned>(all);
809
809
if (ha_info->is_started())
810
810
return; /* already registered, return */
812
812
ha_info->register_ha(trans, ht_arg);
814
814
trans->no_2pc|=(ht_arg->prepare==0);
815
if (thd->transaction.xid_state.xid.is_null())
816
thd->transaction.xid_state.xid.set(thd->query_id);
815
if (session->transaction.xid_state.xid.is_null())
816
session->transaction.xid_state.xid.set(session->query_id);
825
825
1 error, transaction was rolled back
827
int ha_prepare(Session *thd)
827
int ha_prepare(Session *session)
829
829
int error=0, all=1;
830
Session_TRANS *trans=all ? &thd->transaction.all : &thd->transaction.stmt;
830
Session_TRANS *trans=all ? &session->transaction.all : &session->transaction.stmt;
831
831
Ha_trx_info *ha_info= trans->ha_list;
837
837
handlerton *ht= ha_info->ht();
838
status_var_increment(thd->status_var.ha_prepare_count);
838
status_var_increment(session->status_var.ha_prepare_count);
841
if ((err= ht->prepare(ht, thd, all)))
841
if ((err= ht->prepare(ht, session, all)))
843
843
my_error(ER_ERROR_DURING_COMMIT, MYF(0), err);
844
ha_rollback_trans(thd, all);
844
ha_rollback_trans(session, all);
851
push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
851
push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
852
852
ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
853
853
ha_resolve_storage_engine_name(ht));
876
ha_check_and_coalesce_trx_read_only(Session *thd, Ha_trx_info *ha_list,
876
ha_check_and_coalesce_trx_read_only(Session *session, Ha_trx_info *ha_list,
879
879
/* The number of storage engines that have actual changes. */
890
Ha_trx_info *ha_info_all= &thd->ha_data[ha_info->ht()->slot].ha_info[1];
890
Ha_trx_info *ha_info_all= &session->ha_data[ha_info->ht()->slot].ha_info[1];
891
891
assert(ha_info != ha_info_all);
893
893
Merge read-only/read-write information about statement
894
894
transaction to its enclosing normal transaction. Do this
895
895
only if in a real transaction -- that is, if we know
896
that ha_info_all is registered in thd->transaction.all.
896
that ha_info_all is registered in session->transaction.all.
897
897
Since otherwise we only clutter the normal transaction flags.
899
899
if (ha_info_all->is_started()) /* false if autocommit. */
927
927
stored functions or triggers. So we simply do nothing now.
928
928
TODO: This should be fixed in later ( >= 5.1) releases.
930
int ha_commit_trans(Session *thd, bool all)
930
int ha_commit_trans(Session *session, bool all)
932
932
int error= 0, cookie= 0;
934
934
'all' means that this is either an explicit commit issued by
935
935
user, or an implicit commit issued by a DDL.
937
Session_TRANS *trans= all ? &thd->transaction.all : &thd->transaction.stmt;
938
bool is_real_trans= all || thd->transaction.all.ha_list == 0;
937
Session_TRANS *trans= all ? &session->transaction.all : &session->transaction.stmt;
938
bool is_real_trans= all || session->transaction.all.ha_list == 0;
939
939
Ha_trx_info *ha_info= trans->ha_list;
940
my_xid xid= thd->transaction.xid_state.xid.get_my_xid();
940
my_xid xid= session->transaction.xid_state.xid.get_my_xid();
943
943
We must not commit the normal transaction if a statement
945
945
flags will not get propagated to its normal transaction's
948
assert(thd->transaction.stmt.ha_list == NULL ||
949
trans == &thd->transaction.stmt);
948
assert(session->transaction.stmt.ha_list == NULL ||
949
trans == &session->transaction.stmt);
955
if (is_real_trans && wait_if_global_read_lock(thd, 0, 0))
955
if (is_real_trans && wait_if_global_read_lock(session, 0, 0))
957
ha_rollback_trans(thd, all);
957
ha_rollback_trans(session, all);
961
961
if ( is_real_trans
963
&& ! thd->slave_thread
963
&& ! session->slave_thread
966
966
my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--read-only");
967
ha_rollback_trans(thd, all);
967
ha_rollback_trans(session, all);
972
must_2pc= ha_check_and_coalesce_trx_read_only(thd, ha_info, all);
972
must_2pc= ha_check_and_coalesce_trx_read_only(session, ha_info, all);
974
974
if (!trans->no_2pc && must_2pc)
988
988
Sic: we know that prepare() is not NULL since otherwise
989
989
trans->no_2pc would have been set.
991
if ((err= ht->prepare(ht, thd, all)))
991
if ((err= ht->prepare(ht, session, all)))
993
993
my_error(ER_ERROR_DURING_COMMIT, MYF(0), err);
996
status_var_increment(thd->status_var.ha_prepare_count);
996
status_var_increment(session->status_var.ha_prepare_count);
998
998
if (error || (is_real_trans && xid &&
999
(error= !(cookie= tc_log->log_xid(thd, xid)))))
999
(error= !(cookie= tc_log->log_xid(session, xid)))))
1001
ha_rollback_trans(thd, all);
1001
ha_rollback_trans(session, all);
1006
error=ha_commit_one_phase(thd, all) ? (cookie ? 2 : 1) : 0;
1006
error=ha_commit_one_phase(session, all) ? (cookie ? 2 : 1) : 0;
1008
1008
tc_log->unlog(cookie, xid);
1010
1010
if (is_real_trans)
1011
start_waiting_global_read_lock(thd);
1011
start_waiting_global_read_lock(session);
1018
1018
This function does not care about global read lock. A caller should.
1020
int ha_commit_one_phase(Session *thd, bool all)
1020
int ha_commit_one_phase(Session *session, bool all)
1023
Session_TRANS *trans=all ? &thd->transaction.all : &thd->transaction.stmt;
1024
bool is_real_trans=all || thd->transaction.all.ha_list == 0;
1023
Session_TRANS *trans=all ? &session->transaction.all : &session->transaction.stmt;
1024
bool is_real_trans=all || session->transaction.all.ha_list == 0;
1025
1025
Ha_trx_info *ha_info= trans->ha_list, *ha_info_next;
1031
1031
handlerton *ht= ha_info->ht();
1032
if ((err= ht->commit(ht, thd, all)))
1032
if ((err= ht->commit(ht, session, all)))
1034
1034
my_error(ER_ERROR_DURING_COMMIT, MYF(0), err);
1037
status_var_increment(thd->status_var.ha_commit_count);
1037
status_var_increment(session->status_var.ha_commit_count);
1038
1038
ha_info_next= ha_info->next();
1039
1039
ha_info->reset(); /* keep it conveniently zero-filled */
1041
1041
trans->ha_list= 0;
1042
1042
trans->no_2pc=0;
1043
1043
if (is_real_trans)
1044
thd->transaction.xid_state.xid.null();
1044
session->transaction.xid_state.xid.null();
1047
thd->variables.tx_isolation=thd->session_tx_isolation;
1048
thd->transaction.cleanup();
1047
session->variables.tx_isolation=session->session_tx_isolation;
1048
session->transaction.cleanup();
1055
int ha_rollback_trans(Session *thd, bool all)
1055
int ha_rollback_trans(Session *session, bool all)
1058
Session_TRANS *trans=all ? &thd->transaction.all : &thd->transaction.stmt;
1058
Session_TRANS *trans=all ? &session->transaction.all : &session->transaction.stmt;
1059
1059
Ha_trx_info *ha_info= trans->ha_list, *ha_info_next;
1060
bool is_real_trans=all || thd->transaction.all.ha_list == 0;
1060
bool is_real_trans=all || session->transaction.all.ha_list == 0;
1063
1063
We must not rollback the normal transaction if a statement
1064
1064
transaction is pending.
1066
assert(thd->transaction.stmt.ha_list == NULL ||
1067
trans == &thd->transaction.stmt);
1066
assert(session->transaction.stmt.ha_list == NULL ||
1067
trans == &session->transaction.stmt);
1074
1074
handlerton *ht= ha_info->ht();
1075
if ((err= ht->rollback(ht, thd, all)))
1075
if ((err= ht->rollback(ht, session, all)))
1076
1076
{ // cannot happen
1077
1077
my_error(ER_ERROR_DURING_ROLLBACK, MYF(0), err);
1080
status_var_increment(thd->status_var.ha_rollback_count);
1080
status_var_increment(session->status_var.ha_rollback_count);
1081
1081
ha_info_next= ha_info->next();
1082
1082
ha_info->reset(); /* keep it conveniently zero-filled */
1084
1084
trans->ha_list= 0;
1085
1085
trans->no_2pc=0;
1086
1086
if (is_real_trans)
1087
thd->transaction.xid_state.xid.null();
1087
session->transaction.xid_state.xid.null();
1090
thd->variables.tx_isolation=thd->session_tx_isolation;
1091
thd->transaction.cleanup();
1090
session->variables.tx_isolation=session->session_tx_isolation;
1091
session->transaction.cleanup();
1095
thd->transaction_rollback_request= false;
1095
session->transaction_rollback_request= false;
1098
1098
If a non-transactional table was updated, warn; don't warn if this is a
1103
1103
the error log; but we don't want users to wonder why they have this
1104
1104
message in the error log, so we don't send it.
1106
if (is_real_trans && thd->transaction.all.modified_non_trans_table &&
1107
!thd->slave_thread && thd->killed != Session::KILL_CONNECTION)
1108
push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
1106
if (is_real_trans && session->transaction.all.modified_non_trans_table &&
1107
!session->slave_thread && session->killed != Session::KILL_CONNECTION)
1108
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
1109
1109
ER_WARNING_NOT_COMPLETE_ROLLBACK,
1110
1110
ER(ER_WARNING_NOT_COMPLETE_ROLLBACK));
1122
1122
the user has used LOCK TABLES then that mechanism does not know to do the
1125
int ha_autocommit_or_rollback(Session *thd, int error)
1125
int ha_autocommit_or_rollback(Session *session, int error)
1127
if (thd->transaction.stmt.ha_list)
1127
if (session->transaction.stmt.ha_list)
1131
if (ha_commit_trans(thd, 0))
1131
if (ha_commit_trans(session, 0))
1136
(void) ha_rollback_trans(thd, 0);
1137
if (thd->transaction_rollback_request)
1138
(void) ha_rollback(thd);
1136
(void) ha_rollback_trans(session, 0);
1137
if (session->transaction_rollback_request)
1138
(void) ha_rollback(session);
1141
thd->variables.tx_isolation=thd->session_tx_isolation;
1141
session->variables.tx_isolation=session->session_tx_isolation;
1334
1334
so mysql_xa_recover does not filter XID's to ensure uniqueness.
1335
1335
It can be easily fixed later, if necessary.
1337
bool mysql_xa_recover(Session *thd)
1337
bool mysql_xa_recover(Session *session)
1339
1339
List<Item> field_list;
1340
Protocol *protocol= thd->protocol;
1340
Protocol *protocol= session->protocol;
1379
1379
This function should be called when MySQL sends rows of a SELECT result set
1380
1380
or the EOF mark to the client. It releases a possible adaptive hash index
1381
S-latch held by thd in InnoDB and also releases a possible InnoDB query
1382
FIFO ticket to enter InnoDB. To save CPU time, InnoDB allows a thd to
1381
S-latch held by session in InnoDB and also releases a possible InnoDB query
1382
FIFO ticket to enter InnoDB. To save CPU time, InnoDB allows a session to
1383
1383
keep them over several calls of the InnoDB handler interface when a join
1384
1384
is executed. But when we let the control to pass to the client they have
1385
1385
to be released because if the application program uses mysql_use_result(),
1387
1387
performs another SQL query. In MySQL-4.1 this is even more important because
1388
1388
there a connection can have several SELECT queries open at the same time.
1390
@param thd the thread handle of the current connection
1390
@param session the thread handle of the current connection
1395
static bool release_temporary_latches(Session *thd, plugin_ref plugin,
1395
static bool release_temporary_latches(Session *session, plugin_ref plugin,
1396
1396
void *unused __attribute__((unused)))
1398
1398
handlerton *hton= plugin_data(plugin, handlerton *);
1400
1400
if (hton->state == SHOW_OPTION_YES && hton->release_temporary_latches)
1401
hton->release_temporary_latches(hton, thd);
1401
hton->release_temporary_latches(hton, session);
1407
int ha_release_temporary_latches(Session *thd)
1407
int ha_release_temporary_latches(Session *session)
1409
plugin_foreach(thd, release_temporary_latches, DRIZZLE_STORAGE_ENGINE_PLUGIN,
1409
plugin_foreach(session, release_temporary_latches, DRIZZLE_STORAGE_ENGINE_PLUGIN,
1415
int ha_rollback_to_savepoint(Session *thd, SAVEPOINT *sv)
1415
int ha_rollback_to_savepoint(Session *session, SAVEPOINT *sv)
1418
Session_TRANS *trans= &thd->transaction.all;
1418
Session_TRANS *trans= &session->transaction.all;
1419
1419
Ha_trx_info *ha_info, *ha_info_next;
1421
1421
trans->no_2pc=0;
1429
1429
handlerton *ht= ha_info->ht();
1431
1431
assert(ht->savepoint_set != 0);
1432
if ((err= ht->savepoint_rollback(ht, thd,
1432
if ((err= ht->savepoint_rollback(ht, session,
1433
1433
(unsigned char *)(sv+1)+ht->savepoint_offset)))
1434
1434
{ // cannot happen
1435
1435
my_error(ER_ERROR_DURING_ROLLBACK, MYF(0), err);
1438
status_var_increment(thd->status_var.ha_savepoint_rollback_count);
1438
status_var_increment(session->status_var.ha_savepoint_rollback_count);
1439
1439
trans->no_2pc|= ht->prepare == 0;
1449
1449
handlerton *ht= ha_info->ht();
1450
if ((err= ht->rollback(ht, thd, !(0))))
1450
if ((err= ht->rollback(ht, session, !(0))))
1451
1451
{ // cannot happen
1452
1452
my_error(ER_ERROR_DURING_ROLLBACK, MYF(0), err);
1455
status_var_increment(thd->status_var.ha_rollback_count);
1455
status_var_increment(session->status_var.ha_rollback_count);
1456
1456
ha_info_next= ha_info->next();
1457
1457
ha_info->reset(); /* keep it conveniently zero-filled */
1466
1466
section "4.33.4 SQL-statements and transaction states",
1467
1467
SAVEPOINT is *not* transaction-initiating SQL-statement
1469
int ha_savepoint(Session *thd, SAVEPOINT *sv)
1469
int ha_savepoint(Session *session, SAVEPOINT *sv)
1472
Session_TRANS *trans= &thd->transaction.all;
1472
Session_TRANS *trans= &session->transaction.all;
1473
1473
Ha_trx_info *ha_info= trans->ha_list;
1474
1474
for (; ha_info; ha_info= ha_info->next())
1485
if ((err= ht->savepoint_set(ht, thd, (unsigned char *)(sv+1)+ht->savepoint_offset)))
1485
if ((err= ht->savepoint_set(ht, session, (unsigned char *)(sv+1)+ht->savepoint_offset)))
1486
1486
{ // cannot happen
1487
1487
my_error(ER_GET_ERRNO, MYF(0), err);
1490
status_var_increment(thd->status_var.ha_savepoint_count);
1490
status_var_increment(session->status_var.ha_savepoint_count);
1493
1493
Remember the list of registered storage engines. All new
1511
1511
if (!ht->savepoint_release)
1513
if ((err= ht->savepoint_release(ht, thd,
1513
if ((err= ht->savepoint_release(ht, session,
1514
1514
(unsigned char *)(sv+1) + ht->savepoint_offset)))
1515
1515
{ // cannot happen
1516
1516
my_error(ER_GET_ERRNO, MYF(0), err);
1524
static bool snapshot_handlerton(Session *thd, plugin_ref plugin, void *arg)
1524
static bool snapshot_handlerton(Session *session, plugin_ref plugin, void *arg)
1526
1526
handlerton *hton= plugin_data(plugin, handlerton *);
1527
1527
if (hton->state == SHOW_OPTION_YES &&
1528
1528
hton->start_consistent_snapshot)
1530
hton->start_consistent_snapshot(hton, thd);
1530
hton->start_consistent_snapshot(hton, session);
1531
1531
*((bool *)arg)= false;
1536
int ha_start_consistent_snapshot(Session *thd)
1536
int ha_start_consistent_snapshot(Session *session)
1538
1538
bool warn= true;
1540
plugin_foreach(thd, snapshot_handlerton, DRIZZLE_STORAGE_ENGINE_PLUGIN, &warn);
1540
plugin_foreach(session, snapshot_handlerton, DRIZZLE_STORAGE_ENGINE_PLUGIN, &warn);
1543
1543
Same idea as when one wants to CREATE TABLE in one engine which does not
1547
push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
1547
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
1548
1548
"This MySQL server does not support any "
1549
1549
"consistent-read capable storage engine");
1554
static bool flush_handlerton(Session *thd __attribute__((unused)),
1554
static bool flush_handlerton(Session *session __attribute__((unused)),
1555
1555
plugin_ref plugin,
1556
1556
void *arg __attribute__((unused)))
1621
1621
handle_error(uint32_t sql_errno __attribute__((unused)),
1622
1622
const char *message,
1623
1623
DRIZZLE_ERROR::enum_warning_level level __attribute__((unused)),
1624
Session *thd __attribute__((unused)))
1624
Session *session __attribute__((unused)))
1626
1626
/* Grab the error message */
1627
1627
strmake(buff, message, sizeof(buff)-1);
1633
1633
This should return ENOENT if the file doesn't exists.
1634
1634
The .frm file will be deleted only if we return 0 or ENOENT
1636
int ha_delete_table(Session *thd, handlerton *table_type, const char *path,
1636
int ha_delete_table(Session *session, handlerton *table_type, const char *path,
1637
1637
const char *db, const char *alias, bool generate_warning)
1649
1649
/* DB_TYPE_UNKNOWN is used in ALTER Table when renaming only .frm files */
1650
1650
if (table_type == NULL ||
1651
! (file=get_new_handler((TABLE_SHARE*)0, thd->mem_root, table_type)))
1651
! (file=get_new_handler((TABLE_SHARE*)0, session->mem_root, table_type)))
1652
1652
return(ENOENT);
1654
1654
path= check_lowercase_names(file, path, tmp_path);
1674
1674
file->change_table_ptr(&dummy_table, &dummy_share);
1676
thd->push_internal_handler(&ha_delete_table_error_handler);
1676
session->push_internal_handler(&ha_delete_table_error_handler);
1677
1677
file->print_error(error, 0);
1679
thd->pop_internal_handler();
1679
session->pop_internal_handler();
1682
1682
XXX: should we convert *all* errors to warnings here?
1683
1683
What if the error is fatal?
1685
push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_ERROR, error,
1685
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_ERROR, error,
1686
1686
ha_delete_table_error_handler.buff);
1717
1717
status_var_increment(table->in_use->status_var.*offset);
1720
void **handler::ha_data(Session *thd) const
1720
void **handler::ha_data(Session *session) const
1722
return thd_ha_data(thd, ht);
1722
return session_ha_data(session, ht);
1725
Session *handler::ha_thd(void) const
1725
Session *handler::ha_session(void) const
1727
assert(!table || !table->in_use || table->in_use == current_thd);
1728
return (table && table->in_use) ? table->in_use : current_thd;
1727
assert(!table || !table->in_use || table->in_use == current_session);
1728
return (table && table->in_use) ? table->in_use : current_session;
1935
1935
again to reserve a new interval.
1937
1937
- In both cases, the reserved intervals are remembered in
1938
thd->auto_inc_intervals_in_cur_stmt_for_binlog if statement-based
1938
session->auto_inc_intervals_in_cur_stmt_for_binlog if statement-based
1939
1939
binlogging; the last reserved interval is remembered in
1940
1940
auto_inc_interval_for_cur_row.
1949
1949
start counting from the inserted value.
1951
1951
This function's "outputs" are: the table's auto_increment field is filled
1952
with a value, thd->next_insert_id is filled with the value to use for the
1952
with a value, session->next_insert_id is filled with the value to use for the
1953
1953
next row, if a value was autogenerated for the current row it is stored in
1954
thd->insert_id_for_cur_row, if get_auto_increment() was called
1955
thd->auto_inc_interval_for_cur_row is modified, if that interval is not
1956
present in thd->auto_inc_intervals_in_cur_stmt_for_binlog it is added to
1954
session->insert_id_for_cur_row, if get_auto_increment() was called
1955
session->auto_inc_interval_for_cur_row is modified, if that interval is not
1956
present in session->auto_inc_intervals_in_cur_stmt_for_binlog it is added to
1981
1981
uint64_t nr, nb_reserved_values;
1982
1982
bool append= false;
1983
Session *thd= table->in_use;
1984
struct system_variables *variables= &thd->variables;
1983
Session *session= table->in_use;
1984
struct system_variables *variables= &session->variables;
1987
1987
next_insert_id is a "cursor" into the reserved interval, it may go greater
2007
2007
/* next_insert_id is beyond what is reserved, so we reserve more. */
2008
2008
const Discrete_interval *forced=
2009
thd->auto_inc_intervals_forced.get_next();
2009
session->auto_inc_intervals_forced.get_next();
2010
2010
if (forced != NULL)
2012
2012
nr= forced->minimum();
2019
2019
handler::ha_start_bulk_insert(); if 0 it means "unknown".
2021
2021
uint32_t nb_already_reserved_intervals=
2022
thd->auto_inc_intervals_in_cur_stmt_for_binlog.nb_elements();
2022
session->auto_inc_intervals_in_cur_stmt_for_binlog.nb_elements();
2023
2023
uint64_t nb_desired_values;
2025
2025
If an estimation was given to the engine:
2098
2098
auto_inc_interval_for_cur_row.replace(nr, nb_reserved_values,
2099
2099
variables->auto_increment_increment);
2100
2100
/* Row-based replication does not need to store intervals in binlog */
2101
if (!thd->current_stmt_binlog_row_based)
2102
thd->auto_inc_intervals_in_cur_stmt_for_binlog.append(auto_inc_interval_for_cur_row.minimum(),
2101
if (!session->current_stmt_binlog_row_based)
2102
session->auto_inc_intervals_in_cur_stmt_for_binlog.append(auto_inc_interval_for_cur_row.minimum(),
2103
2103
auto_inc_interval_for_cur_row.values(),
2104
2104
variables->auto_increment_increment);
2655
2655
if (!error && (check_opt->sql_flags & TT_FOR_UPGRADE))
2658
if ((error= check(thd, check_opt)))
2658
if ((error= check(session, check_opt)))
2660
2660
return update_frm_version(table);
2670
2670
handler::mark_trx_read_write()
2672
Ha_trx_info *ha_info= &ha_thd()->ha_data[ht->slot].ha_info[0];
2672
Ha_trx_info *ha_info= &ha_session()->ha_data[ht->slot].ha_info[0];
2674
2674
When a storage engine method is called, the transaction must
2675
2675
have been started, unless it's a DDL call, for which the
2697
2697
@sa handler::repair()
2700
int handler::ha_repair(Session* thd, HA_CHECK_OPT* check_opt)
2700
int handler::ha_repair(Session* session, HA_CHECK_OPT* check_opt)
2704
2704
mark_trx_read_write();
2706
if ((result= repair(thd, check_opt)))
2706
if ((result= repair(session, check_opt)))
2708
2708
return update_frm_version(table);
2765
handler::ha_optimize(Session* thd, HA_CHECK_OPT* check_opt)
2765
handler::ha_optimize(Session* session, HA_CHECK_OPT* check_opt)
2767
2767
mark_trx_read_write();
2769
return optimize(thd, check_opt);
2769
return optimize(session, check_opt);
2780
handler::ha_analyze(Session* thd, HA_CHECK_OPT* check_opt)
2780
handler::ha_analyze(Session* session, HA_CHECK_OPT* check_opt)
2782
2782
mark_trx_read_write();
2784
return analyze(thd, check_opt);
2784
return analyze(session, check_opt);
2946
2946
starts to commit every now and then automatically.
2947
2947
This hint can be safely ignored.
2949
int ha_enable_transaction(Session *thd, bool on)
2949
int ha_enable_transaction(Session *session, bool on)
2953
if ((thd->transaction.on= on))
2953
if ((session->transaction.on= on))
2956
2956
Now all storage engines should have transaction handling enabled.
2958
2958
is an optimization hint that storage engine is free to ignore.
2959
2959
So, let's commit an open transaction (if any) now.
2961
if (!(error= ha_commit_trans(thd, 0)))
2962
error= end_trans(thd, COMMIT);
2961
if (!(error= ha_commit_trans(session, 0)))
2962
error= end_trans(session, COMMIT);
3030
int ha_create_table(Session *thd, const char *path,
3030
int ha_create_table(Session *session, const char *path,
3031
3031
const char *db, const char *table_name,
3032
3032
HA_CREATE_INFO *create_info,
3033
3033
bool update_create_info)
3038
3038
const char *name;
3039
3039
TABLE_SHARE share;
3041
init_tmp_table_share(thd, &share, db, 0, table_name, path);
3042
if (open_table_def(thd, &share, 0) ||
3043
open_table_from_share(thd, &share, "", 0, (uint) READ_ALL, 0, &table,
3041
init_tmp_table_share(session, &share, db, 0, table_name, path);
3042
if (open_table_def(session, &share, 0) ||
3043
open_table_from_share(session, &share, "", 0, (uint) READ_ALL, 0, &table,
3075
3075
> 0 Error, table existed but could not be created
3077
int ha_create_table_from_engine(Session* thd, const char *db, const char *name)
3077
int ha_create_table_from_engine(Session* session, const char *db, const char *name)
3080
3080
unsigned char *frmblob;
3085
3085
TABLE_SHARE share;
3087
3087
memset(&create_info, 0, sizeof(create_info));
3088
if ((error= ha_discover(thd, db, name, &frmblob, &frmlen)))
3088
if ((error= ha_discover(session, db, name, &frmblob, &frmlen)))
3090
3090
/* Table could not be discovered and thus not created */
3106
init_tmp_table_share(thd, &share, db, 0, name, path);
3107
if (open_table_def(thd, &share, 0))
3106
init_tmp_table_share(session, &share, db, 0, name, path);
3107
if (open_table_def(session, &share, 0))
3111
if (open_table_from_share(thd, &share, "" ,0, 0, 0, &table, OTM_OPEN))
3111
if (open_table_from_share(session, &share, "" ,0, 0, 0, &table, OTM_OPEN))
3113
3113
free_table_share(&share);
3239
3239
size_t *frmlen;
3242
static bool discover_handlerton(Session *thd, plugin_ref plugin,
3242
static bool discover_handlerton(Session *session, plugin_ref plugin,
3245
3245
st_discover_args *vargs= (st_discover_args *)arg;
3246
3246
handlerton *hton= plugin_data(plugin, handlerton *);
3247
3247
if (hton->state == SHOW_OPTION_YES && hton->discover &&
3248
(!(hton->discover(hton, thd, vargs->db, vargs->name,
3248
(!(hton->discover(hton, session, vargs->db, vargs->name,
3249
3249
vargs->frmblob,
3250
3250
vargs->frmlen))))
3256
int ha_discover(Session *thd, const char *db, const char *name,
3256
int ha_discover(Session *session, const char *db, const char *name,
3257
3257
unsigned char **frmblob, size_t *frmlen)
3259
3259
int error= -1; // Table does not exist in any handler
3262
3262
if (is_prefix(name,tmp_file_prefix)) /* skip temporary tables */
3265
if (plugin_foreach(thd, discover_handlerton,
3265
if (plugin_foreach(session, discover_handlerton,
3266
3266
DRIZZLE_STORAGE_ENGINE_PLUGIN, &args))
3270
status_var_increment(thd->status_var.ha_discover_count);
3270
status_var_increment(session->status_var.ha_discover_count);
3305
static bool table_exists_in_engine_handlerton(Session *thd, plugin_ref plugin,
3305
static bool table_exists_in_engine_handlerton(Session *session, plugin_ref plugin,
3308
3308
st_table_exists_in_engine_args *vargs= (st_table_exists_in_engine_args *)arg;
3311
3311
int err= HA_ERR_NO_SUCH_TABLE;
3313
3313
if (hton->state == SHOW_OPTION_YES && hton->table_exists_in_engine)
3314
err = hton->table_exists_in_engine(hton, thd, vargs->db, vargs->name);
3314
err = hton->table_exists_in_engine(hton, session, vargs->db, vargs->name);
3316
3316
vargs->err = err;
3317
3317
if (vargs->err == HA_ERR_TABLE_EXIST)
3323
int ha_table_exists_in_engine(Session* thd, const char* db, const char* name)
3323
int ha_table_exists_in_engine(Session* session, const char* db, const char* name)
3325
3325
st_table_exists_in_engine_args args= {db, name, HA_ERR_NO_SUCH_TABLE};
3326
plugin_foreach(thd, table_exists_in_engine_handlerton,
3326
plugin_foreach(session, table_exists_in_engine_handlerton,
3327
3327
DRIZZLE_STORAGE_ENGINE_PLUGIN, &args);
3328
3328
return(args.err);
3385
3385
This method (or an overriding one in a derived class) must check for
3386
thd->killed and return HA_POS_ERROR if it is not zero. This is required
3386
session->killed and return HA_POS_ERROR if it is not zero. This is required
3387
3387
for a user to be able to interrupt the calculation by killing the
3388
3388
connection/query.
3405
3405
range_seq_t seq_it;
3406
3406
ha_rows rows, total_rows= 0;
3407
3407
uint32_t n_ranges=0;
3408
Session *thd= current_thd;
3408
Session *session= current_session;
3410
3410
/* Default MRR implementation doesn't need buffer */
3413
3413
seq_it= seq->init(seq_init_param, n_ranges, *flags);
3414
3414
while (!seq->next(seq_it, &range))
3416
if (unlikely(thd->killed != 0))
3416
if (unlikely(session->killed != 0))
3417
3417
return HA_POS_ERROR;
3679
3679
rowids_buf_end= rowids_buf_last;
3681
3681
/* Create a separate handler object to do rndpos() calls. */
3682
Session *thd= current_thd;
3683
if (!(new_h2= h->clone(thd->mem_root)) ||
3684
new_h2->ha_external_lock(thd, F_RDLCK))
3682
Session *session= current_session;
3683
if (!(new_h2= h->clone(session->mem_root)) ||
3684
new_h2->ha_external_lock(session, F_RDLCK))
3975
3975
COST_VECT dsmrr_cost;
3977
Session *thd= current_thd;
3978
if ((thd->variables.optimizer_use_mrr == 2) ||
3977
Session *session= current_session;
3978
if ((session->variables.optimizer_use_mrr == 2) ||
3979
3979
(*flags & HA_MRR_INDEX_ONLY) || (*flags & HA_MRR_SORTED) ||
3980
3980
(keyno == table->s->primary_key &&
3981
3981
h->primary_key_is_clustered()) ||
3999
3999
DS-MRR whenever it is applicable without affecting other cost-based
4002
if ((force_dsmrr= (thd->variables.optimizer_use_mrr == 1)) &&
4002
if ((force_dsmrr= (session->variables.optimizer_use_mrr == 1)) &&
4003
4003
dsmrr_cost.total_cost() > cost->total_cost())
4004
4004
dsmrr_cost= *cost;
4360
4360
handlerton *hton= plugin_data(plugin, handlerton *);
4362
4362
if (hton->state == SHOW_OPTION_YES && hton->create &&
4363
(file= hton->create(hton, (TABLE_SHARE*) 0, current_thd->mem_root)))
4363
(file= hton->create(hton, (TABLE_SHARE*) 0, current_session->mem_root)))
4365
4365
List_iterator_fast<char> it(*found_exts);
4366
4366
const char **ext, *old_ext;
4414
static bool stat_print(Session *thd, const char *type, uint32_t type_len,
4414
static bool stat_print(Session *session, const char *type, uint32_t type_len,
4415
4415
const char *file, uint32_t file_len,
4416
4416
const char *status, uint32_t status_len)
4418
Protocol *protocol= thd->protocol;
4418
Protocol *protocol= session->protocol;
4419
4419
protocol->prepare_for_resend();
4420
4420
protocol->store(type, type_len, system_charset_info);
4421
4421
protocol->store(file, file_len, system_charset_info);
4428
bool ha_show_status(Session *thd, handlerton *db_type, enum ha_stat_type stat)
4428
bool ha_show_status(Session *session, handlerton *db_type, enum ha_stat_type stat)
4430
4430
List<Item> field_list;
4431
Protocol *protocol= thd->protocol;
4431
Protocol *protocol= session->protocol;
4434
4434
field_list.push_back(new Item_empty_string("Type",10));
4442
4442
result= db_type->show_status &&
4443
db_type->show_status(db_type, thd, stat_print, stat) ? 1 : 0;
4443
db_type->show_status(db_type, session, stat_print, stat) ? 1 : 0;
4460
4460
- table is not mysql.event
4463
static bool check_table_binlog_row_based(Session *thd, Table *table)
4463
static bool check_table_binlog_row_based(Session *session, Table *table)
4465
4465
if (table->s->cached_row_logging_check == -1)
4472
4472
assert(table->s->cached_row_logging_check == 0 ||
4473
4473
table->s->cached_row_logging_check == 1);
4475
return (thd->current_stmt_binlog_row_based &&
4475
return (session->current_stmt_binlog_row_based &&
4476
4476
table->s->cached_row_logging_check &&
4477
(thd->options & OPTION_BIN_LOG) &&
4477
(session->options & OPTION_BIN_LOG) &&
4478
4478
mysql_bin_log.is_open());
4484
4484
to the binary log.
4486
4486
This function will generate and write table maps for all tables
4487
that are locked by the thread 'thd'. Either manually locked
4487
that are locked by the thread 'session'. Either manually locked
4488
4488
(stored in Session::locked_tables) and automatically locked (stored
4489
4489
in Session::lock) are considered.
4491
@param thd Pointer to Session structure
4491
@param session Pointer to Session structure
4493
4493
@retval 0 All OK
4494
4494
@retval 1 Failed to write all table maps
4498
4498
Session::locked_tables
4501
static int write_locked_table_maps(Session *thd)
4501
static int write_locked_table_maps(Session *session)
4503
if (thd->get_binlog_table_maps() == 0)
4503
if (session->get_binlog_table_maps() == 0)
4505
4505
DRIZZLE_LOCK *locks[3];
4506
locks[0]= thd->extra_lock;
4507
locks[1]= thd->lock;
4508
locks[2]= thd->locked_tables;
4506
locks[0]= session->extra_lock;
4507
locks[1]= session->lock;
4508
locks[2]= session->locked_tables;
4509
4509
for (uint32_t i= 0 ; i < sizeof(locks)/sizeof(*locks) ; ++i )
4511
4511
DRIZZLE_LOCK const *const lock= locks[i];
4520
4520
Table *const table= *table_ptr;
4521
4521
if (table->current_lock == F_WRLCK &&
4522
check_table_binlog_row_based(thd, table))
4522
check_table_binlog_row_based(session, table))
4524
4524
int const has_trans= table->file->has_transactions();
4525
int const error= thd->binlog_write_table_map(table, has_trans);
4525
int const error= session->binlog_write_table_map(table, has_trans);
4527
4527
If an error occurs, it is the responsibility of the caller to
4528
4528
roll back the transaction.
4547
4547
if (table->no_replicate)
4550
Session *const thd= table->in_use;
4550
Session *const session= table->in_use;
4552
if (check_table_binlog_row_based(thd, table))
4552
if (check_table_binlog_row_based(session, table))
4555
4555
If there are no table maps written to the binary log, this is
4556
4556
the first row handled in this statement. In that case, we need
4557
4557
to write table maps for all locked tables to the binary log.
4559
if (likely(!(error= write_locked_table_maps(thd))))
4559
if (likely(!(error= write_locked_table_maps(session))))
4561
4561
bool const has_trans= table->file->has_transactions();
4562
error= (*log_func)(thd, table, has_trans, before_record, after_record);
4562
error= (*log_func)(session, table, has_trans, before_record, after_record);
4565
4565
return error ? HA_ERR_RBR_LOGGING_FAILED : 0;
4568
int handler::ha_external_lock(Session *thd, int lock_type)
4568
int handler::ha_external_lock(Session *session, int lock_type)
4571
4571
Whether this is lock or unlock, this should be true, and is to verify that
4581
4581
DRIZZLE_EXTERNAL_LOCK(lock_type);
4583
int error= external_lock(thd, lock_type);
4583
int error= external_lock(session, lock_type);
4584
4584
if (error == 0)
4585
4585
cached_table_flags= table_flags();