1
/* Copyright (C) 2000-2006 MySQL AB
3
This program is free software; you can redistribute it and/or modify
4
it under the terms of the GNU General Public License as published by
5
the Free Software Foundation; version 2 of the License.
7
This program is distributed in the hope that it will be useful,
8
but WITHOUT ANY WARRANTY; without even the implied warranty of
9
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
GNU General Public License for more details.
12
You should have received a copy of the GNU General Public License
13
along with this program; if not, write to the Free Software
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
4
* Copyright (C) 2008 Sun Microsystems
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; version 2 of the License.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19
23
Handler-calling-functions
22
#ifdef USE_PRAGMA_IMPLEMENTATION
23
#pragma implementation // gcc: Class implementation
26
26
#include <drizzled/server_includes.h>
27
#include "rpl_filter.h"
28
#include <drizzled/drizzled_error_messages.h>
31
While we have legacy_db_type, we have this array to
32
check for dups and to find handlerton from legacy_db_type.
33
Remove when legacy_db_type is finally gone
35
st_plugin_int *hton2plugin[MAX_HA];
37
static handlerton *installed_htons[128];
39
#define BITMAP_STACKBUF_SIZE (128/8)
41
KEY_CREATE_INFO default_key_create_info= { HA_KEY_ALG_UNDEF, 0, {NullS,0}, {NullS,0} };
27
#include <libdrizzle/libdrizzle.h>
28
#include <mysys/hash.h>
29
#include <drizzled/error.h>
30
#include <drizzled/gettext.h>
31
#include <drizzled/data_home.h>
32
#include <drizzled/probes.h>
33
#include <drizzled/sql_parse.h>
34
#include <drizzled/cost_vect.h>
36
#include <drizzled/session.h>
37
#include <drizzled/sql_base.h>
38
#include <drizzled/replicator.h>
39
#include <drizzled/lock.h>
40
#include <drizzled/item/int.h>
41
#include <drizzled/item/empty_string.h>
42
#include <drizzled/unireg.h> // for mysql_frm_type
44
#if defined(CMATH_NAMESPACE)
45
using namespace CMATH_NAMESPACE;
49
extern HASH open_cache;
51
KEY_CREATE_INFO default_key_create_info= { HA_KEY_ALG_UNDEF, 0, {NULL,0}, {NULL,0} };
43
53
/* number of entries in handlertons[] */
44
54
uint32_t total_ha= 0;
47
57
/* size of savepoint storage area (see ha_init) */
48
58
uint32_t savepoint_alloc_size= 0;
50
static const LEX_STRING sys_table_aliases[]=
52
{ C_STRING_WITH_LEN("INNOBASE") }, { C_STRING_WITH_LEN("INNODB") },
53
{ C_STRING_WITH_LEN("HEAP") }, { C_STRING_WITH_LEN("MEMORY") },
57
60
const char *ha_row_type[] = {
58
61
"", "FIXED", "DYNAMIC", "COMPRESSED", "REDUNDANT", "COMPACT", "PAGE", "?","?","?"
61
64
const char *tx_isolation_names[] =
62
65
{ "READ-UNCOMMITTED", "READ-COMMITTED", "REPEATABLE-READ", "SERIALIZABLE",
64
68
TYPELIB tx_isolation_typelib= {array_elements(tx_isolation_names)-1,"",
65
tx_isolation_names, NULL};
69
tx_isolation_names, NULL};
67
71
static TYPELIB known_extensions= {0,"known_exts", NULL, NULL};
68
uint known_extensions_id= 0;
72
static plugin_ref ha_default_plugin(THD *thd)
74
if (thd->variables.table_plugin)
75
return thd->variables.table_plugin;
76
return my_plugin_lock(thd, &global_system_variables.table_plugin);
81
Return the default storage engine handlerton for thread
83
@param ha_default_handlerton(thd)
84
@param thd current thread
89
handlerton *ha_default_handlerton(THD *thd)
91
plugin_ref plugin= ha_default_plugin(thd);
93
handlerton *hton= plugin_data(plugin, handlerton*);
100
Return the storage engine handlerton for the supplied name
102
@param thd current thread
103
@param name name of storage engine
106
pointer to storage engine plugin handle
108
plugin_ref ha_resolve_by_name(THD *thd, const LEX_STRING *name)
110
const LEX_STRING *table_alias;
114
/* my_strnncoll is a macro and gcc doesn't do early expansion of macro */
115
if (thd && !my_charset_latin1.coll->strnncoll(&my_charset_latin1,
116
(const uchar *)name->str, name->length,
117
(const uchar *)STRING_WITH_LEN("DEFAULT"), 0))
118
return ha_default_plugin(thd);
120
if ((plugin= my_plugin_lock_by_name(thd, name, DRIZZLE_STORAGE_ENGINE_PLUGIN)))
122
handlerton *hton= plugin_data(plugin, handlerton *);
123
if (!(hton->flags & HTON_NOT_USER_SELECTABLE))
127
unlocking plugin immediately after locking is relatively low cost.
129
plugin_unlock(thd, plugin);
133
We check for the historical aliases.
135
for (table_alias= sys_table_aliases; table_alias->str; table_alias+= 2)
137
if (!my_strnncoll(&my_charset_latin1,
138
(const uchar *)name->str, name->length,
139
(const uchar *)table_alias->str, table_alias->length))
141
name= table_alias + 1;
150
plugin_ref ha_lock_engine(THD *thd, handlerton *hton)
154
st_plugin_int **plugin= hton2plugin + hton->slot;
156
return my_plugin_lock(thd, &plugin);
162
handlerton *ha_resolve_by_legacy_type(THD *thd, enum legacy_db_type db_type)
166
case DB_TYPE_DEFAULT:
167
return ha_default_handlerton(thd);
169
if (db_type > DB_TYPE_UNKNOWN && db_type < DB_TYPE_DEFAULT &&
170
(plugin= ha_lock_engine(thd, installed_htons[db_type])))
171
return plugin_data(plugin, handlerton*);
173
case DB_TYPE_UNKNOWN:
180
Use other database handler if databasehandler is not compiled in.
182
handlerton *ha_checktype(THD *thd, enum legacy_db_type database_type,
183
bool no_substitute, bool report_error)
185
handlerton *hton= ha_resolve_by_legacy_type(thd, database_type);
186
if (ha_storage_engine_is_enabled(hton))
193
const char *engine_name= ha_resolve_storage_engine_name(hton);
194
my_error(ER_FEATURE_DISABLED,MYF(0),engine_name,engine_name);
199
switch (database_type) {
201
return ha_resolve_by_legacy_type(thd, DB_TYPE_HASH);
206
return ha_default_handlerton(thd);
210
handler *get_new_handler(TABLE_SHARE *share, MEM_ROOT *alloc,
215
if (db_type && db_type->state == SHOW_OPTION_YES && db_type->create)
217
if ((file= db_type->create(db_type, share, alloc)))
222
Try the default table type
223
Here the call to current_thd() is ok as we call this function a lot of
224
times but we enter this branch very seldom.
226
return(get_new_handler(share, alloc, ha_default_handlerton(current_thd)));
72
uint32_t known_extensions_id= 0;
310
155
/* Allocate a pointer array for the error message strings. */
311
156
if (! (errmsgs= my_error_unregister(HA_ERR_FIRST, HA_ERR_LAST)))
313
my_free((uchar*) errmsgs, MYF(0));
158
free((unsigned char*) errmsgs);
318
int ha_finalize_handlerton(st_plugin_int *plugin)
320
handlerton *hton= (handlerton *)plugin->data;
325
case SHOW_OPTION_DISABLED:
327
case SHOW_OPTION_YES:
328
if (installed_htons[hton->db_type] == hton)
329
installed_htons[hton->db_type]= NULL;
333
if (hton && plugin->plugin->deinit)
334
(void)plugin->plugin->deinit(hton);
336
my_free((uchar*)hton, MYF(0));
342
int ha_initialize_handlerton(st_plugin_int *plugin)
346
hton= (handlerton *)my_malloc(sizeof(handlerton),
347
MYF(MY_WME | MY_ZEROFILL));
349
FIXME: the MY_ZEROFILL flag above doesn't zero all the bytes.
351
This was detected after adding get_backup_engine member to handlerton
352
structure. Apparently get_backup_engine was not NULL even though it was
355
memset(hton, 0, sizeof(hton));
356
/* Historical Requirement */
357
plugin->data= hton; // shortcut for the future
358
if (plugin->plugin->init)
360
if (plugin->plugin->init(hton))
362
sql_print_error("Plugin '%s' init function returned error.",
369
the switch below and hton->state should be removed when
370
command-line options for plugins will be implemented
372
switch (hton->state) {
375
case SHOW_OPTION_YES:
378
/* now check the db_type for conflict */
379
if (hton->db_type <= DB_TYPE_UNKNOWN ||
380
hton->db_type >= DB_TYPE_DEFAULT ||
381
installed_htons[hton->db_type])
383
int idx= (int) DB_TYPE_FIRST_DYNAMIC;
385
while (idx < (int) DB_TYPE_DEFAULT && installed_htons[idx])
388
if (idx == (int) DB_TYPE_DEFAULT)
390
sql_print_warning("Too many storage engines!");
393
if (hton->db_type != DB_TYPE_UNKNOWN)
394
sql_print_warning("Storage engine '%s' has conflicting typecode. "
395
"Assigning value %d.", plugin->plugin->name, idx);
396
hton->db_type= (enum legacy_db_type) idx;
398
installed_htons[hton->db_type]= hton;
399
tmp= hton->savepoint_offset;
400
hton->savepoint_offset= savepoint_alloc_size;
401
savepoint_alloc_size+= tmp;
402
hton->slot= total_ha++;
403
hton2plugin[hton->slot]=plugin;
410
hton->state= SHOW_OPTION_DISABLED;
415
This is entirely for legacy. We will create a new "disk based" hton and a
416
"memory" hton which will be configurable longterm. We should be able to
417
remove partition and myisammrg.
419
switch (hton->db_type) {
607
334
The server stores its transaction-related data in
608
thd->transaction. This structure has two members of type
609
THD_TRANS. These members correspond to the statement and
335
session->transaction. This structure has two members of type
336
Session_TRANS. These members correspond to the statement and
610
337
normal transactions respectively:
612
- thd->transaction.stmt contains a list of engines
339
- session->transaction.stmt contains a list of engines
613
340
that are participating in the given statement
614
- thd->transaction.all contains a list of engines that
341
- session->transaction.all contains a list of engines that
615
342
have participated in any of the statement transactions started
616
343
within the context of the normal transaction.
617
344
Each element of the list contains a pointer to the storage
618
345
engine, engine-specific transactional data, and engine-specific
619
346
transaction flags.
621
In autocommit mode thd->transaction.all is empty.
622
Instead, data of thd->transaction.stmt is
348
In autocommit mode session->transaction.all is empty.
349
Instead, data of session->transaction.stmt is
623
350
used to commit/rollback the normal transaction.
625
352
The list of registered engines has a few important properties:
855
582
handlerton *ht= ha_info->ht();
856
status_var_increment(thd->status_var.ha_prepare_count);
583
status_var_increment(session->status_var.ha_prepare_count);
859
if ((err= ht->prepare(ht, thd, all)))
586
if ((err= ht->prepare(ht, session, all)))
861
588
my_error(ER_ERROR_DURING_COMMIT, MYF(0), err);
862
ha_rollback_trans(thd, all);
589
ha_rollback_trans(session, all);
869
push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
596
push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
870
597
ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
871
598
ha_resolve_storage_engine_name(ht));
945
672
stored functions or triggers. So we simply do nothing now.
946
673
TODO: This should be fixed in later ( >= 5.1) releases.
948
int ha_commit_trans(THD *thd, bool all)
675
int ha_commit_trans(Session *session, bool all)
950
677
int error= 0, cookie= 0;
952
679
'all' means that this is either an explicit commit issued by
953
680
user, or an implicit commit issued by a DDL.
955
THD_TRANS *trans= all ? &thd->transaction.all : &thd->transaction.stmt;
956
bool is_real_trans= all || thd->transaction.all.ha_list == 0;
682
Session_TRANS *trans= all ? &session->transaction.all : &session->transaction.stmt;
683
bool is_real_trans= all || session->transaction.all.ha_list == 0;
957
684
Ha_trx_info *ha_info= trans->ha_list;
958
my_xid xid= thd->transaction.xid_state.xid.get_my_xid();
685
my_xid xid= session->transaction.xid_state.xid.get_my_xid();
961
688
We must not commit the normal transaction if a statement
963
690
flags will not get propagated to its normal transaction's
966
assert(thd->transaction.stmt.ha_list == NULL ||
967
trans == &thd->transaction.stmt);
693
assert(session->transaction.stmt.ha_list == NULL ||
694
trans == &session->transaction.stmt);
969
if (thd->in_sub_stmt)
972
Since we don't support nested statement transactions in 5.0,
973
we can't commit or rollback stmt transactions while we are inside
974
stored functions or triggers. So we simply do nothing now.
975
TODO: This should be fixed in later ( >= 5.1) releases.
980
We assume that all statements which commit or rollback main transaction
981
are prohibited inside of stored functions or triggers. So they should
982
bail out with error even before ha_commit_trans() call. To be 100% safe
983
let us throw error in non-debug builds.
986
my_error(ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0));
993
if (is_real_trans && wait_if_global_read_lock(thd, 0, 0))
700
if (is_real_trans && wait_if_global_read_lock(session, 0, 0))
995
ha_rollback_trans(thd, all);
702
ha_rollback_trans(session, all);
1001
&& ! thd->slave_thread
1004
my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--read-only");
1005
ha_rollback_trans(thd, all);
1010
must_2pc= ha_check_and_coalesce_trx_read_only(thd, ha_info, all);
706
must_2pc= ha_check_and_coalesce_trx_read_only(session, ha_info, all);
1012
708
if (!trans->no_2pc && must_2pc)
1026
722
Sic: we know that prepare() is not NULL since otherwise
1027
723
trans->no_2pc would have been set.
1029
if ((err= ht->prepare(ht, thd, all)))
725
if ((err= ht->prepare(ht, session, all)))
1031
727
my_error(ER_ERROR_DURING_COMMIT, MYF(0), err);
1034
status_var_increment(thd->status_var.ha_prepare_count);
730
status_var_increment(session->status_var.ha_prepare_count);
1036
732
if (error || (is_real_trans && xid &&
1037
(error= !(cookie= tc_log->log_xid(thd, xid)))))
733
(error= !(cookie= tc_log->log_xid(session, xid)))))
1039
ha_rollback_trans(thd, all);
735
ha_rollback_trans(session, all);
1044
error=ha_commit_one_phase(thd, all) ? (cookie ? 2 : 1) : 0;
740
error=ha_commit_one_phase(session, all) ? (cookie ? 2 : 1) : 0;
1046
742
tc_log->unlog(cookie, xid);
1048
744
if (is_real_trans)
1049
start_waiting_global_read_lock(thd);
745
start_waiting_global_read_lock(session);
1069
765
handlerton *ht= ha_info->ht();
1070
if ((err= ht->commit(ht, thd, all)))
766
if ((err= ht->commit(ht, session, all)))
1072
768
my_error(ER_ERROR_DURING_COMMIT, MYF(0), err);
1075
status_var_increment(thd->status_var.ha_commit_count);
771
status_var_increment(session->status_var.ha_commit_count);
1076
772
ha_info_next= ha_info->next();
1077
773
ha_info->reset(); /* keep it conveniently zero-filled */
1079
775
trans->ha_list= 0;
1080
776
trans->no_2pc=0;
1081
777
if (is_real_trans)
1082
thd->transaction.xid_state.xid.null();
778
session->transaction.xid_state.xid.null();
1085
thd->variables.tx_isolation=thd->session_tx_isolation;
1086
thd->transaction.cleanup();
781
session->variables.tx_isolation=session->session_tx_isolation;
782
session->transaction.cleanup();
1093
int ha_rollback_trans(THD *thd, bool all)
789
int ha_rollback_trans(Session *session, bool all)
1096
THD_TRANS *trans=all ? &thd->transaction.all : &thd->transaction.stmt;
792
Session_TRANS *trans=all ? &session->transaction.all : &session->transaction.stmt;
1097
793
Ha_trx_info *ha_info= trans->ha_list, *ha_info_next;
1098
bool is_real_trans=all || thd->transaction.all.ha_list == 0;
794
bool is_real_trans=all || session->transaction.all.ha_list == 0;
1101
797
We must not rollback the normal transaction if a statement
1102
798
transaction is pending.
1104
assert(thd->transaction.stmt.ha_list == NULL ||
1105
trans == &thd->transaction.stmt);
800
assert(session->transaction.stmt.ha_list == NULL ||
801
trans == &session->transaction.stmt);
1107
if (thd->in_sub_stmt)
1110
If we are inside stored function or trigger we should not commit or
1111
rollback current statement transaction. See comment in ha_commit_trans()
1112
call for more information.
1117
my_error(ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0));
1122
805
for (; ha_info; ha_info= ha_info_next)
1125
808
handlerton *ht= ha_info->ht();
1126
if ((err= ht->rollback(ht, thd, all)))
809
if ((err= ht->rollback(ht, session, all)))
1127
810
{ // cannot happen
1128
811
my_error(ER_ERROR_DURING_ROLLBACK, MYF(0), err);
1131
status_var_increment(thd->status_var.ha_rollback_count);
814
status_var_increment(session->status_var.ha_rollback_count);
1132
815
ha_info_next= ha_info->next();
1133
816
ha_info->reset(); /* keep it conveniently zero-filled */
1135
818
trans->ha_list= 0;
1136
819
trans->no_2pc=0;
1137
820
if (is_real_trans)
1138
thd->transaction.xid_state.xid.null();
821
session->transaction.xid_state.xid.null();
1141
thd->variables.tx_isolation=thd->session_tx_isolation;
1142
thd->transaction.cleanup();
824
session->variables.tx_isolation=session->session_tx_isolation;
825
session->transaction.cleanup();
1146
thd->transaction_rollback_request= false;
829
session->transaction_rollback_request= false;
1149
832
If a non-transactional table was updated, warn; don't warn if this is a
1173
856
the user has used LOCK TABLES then that mechanism does not know to do the
1176
int ha_autocommit_or_rollback(THD *thd, int error)
859
int ha_autocommit_or_rollback(Session *session, int error)
1178
if (thd->transaction.stmt.ha_list)
861
if (session->transaction.stmt.ha_list)
1182
if (ha_commit_trans(thd, 0))
865
if (ha_commit_trans(session, 0))
1187
(void) ha_rollback_trans(thd, 0);
1188
if (thd->transaction_rollback_request && !thd->in_sub_stmt)
1189
(void) ha_rollback(thd);
870
(void) ha_rollback_trans(session, 0);
871
if (session->transaction_rollback_request)
872
(void) ha_rollback(session);
1192
thd->variables.tx_isolation=thd->session_tx_isolation;
875
session->variables.tx_isolation=session->session_tx_isolation;
1357
plugin_foreach(NULL, xarecover_handlerton,
1040
plugin_foreach(NULL, xarecover_handlerton,
1358
1041
DRIZZLE_STORAGE_ENGINE_PLUGIN, &info);
1360
my_free((uchar*)info.list, MYF(0));
1043
free((unsigned char*)info.list);
1361
1044
if (info.found_foreign_xids)
1362
sql_print_warning("Found %d prepared XA transactions",
1045
sql_print_warning(_("Found %d prepared XA transactions"),
1363
1046
info.found_foreign_xids);
1364
1047
if (info.dry_run && info.found_my_xids)
1366
sql_print_error("Found %d prepared transactions! It means that mysqld was "
1367
"not shut down properly last time and critical recovery "
1368
"information (last binlog or %s file) was manually deleted "
1369
"after a crash. You have to start mysqld with "
1370
"--tc-heuristic-recover switch to commit or rollback "
1371
"pending transactions.",
1049
sql_print_error(_("Found %d prepared transactions! It means that drizzled "
1050
"was not shut down properly last time and critical "
1051
"recovery information (last binlog or %s file) was "
1052
"manually deleted after a crash. You have to start "
1053
"drizzled with the --tc-heuristic-recover switch to "
1054
"commit or rollback pending transactions."),
1372
1055
info.found_my_xids, opt_tc_log_file);
1375
1058
if (info.commit_list)
1376
sql_print_information("Crash recovery finished.");
1059
sql_print_information(_("Crash recovery finished."));
1438
1121
performs another SQL query. In MySQL-4.1 this is even more important because
1439
1122
there a connection can have several SELECT queries open at the same time.
1441
@param thd the thread handle of the current connection
1124
@param session the thread handle of the current connection
1446
static bool release_temporary_latches(THD *thd, plugin_ref plugin,
1129
static bool release_temporary_latches(Session *session, plugin_ref plugin,
1447
1130
void *unused __attribute__((unused)))
1449
1132
handlerton *hton= plugin_data(plugin, handlerton *);
1451
1134
if (hton->state == SHOW_OPTION_YES && hton->release_temporary_latches)
1452
hton->release_temporary_latches(hton, thd);
1135
hton->release_temporary_latches(hton, session);
1458
int ha_release_temporary_latches(THD *thd)
1141
int ha_release_temporary_latches(Session *session)
1460
plugin_foreach(thd, release_temporary_latches, DRIZZLE_STORAGE_ENGINE_PLUGIN,
1143
plugin_foreach(session, release_temporary_latches, DRIZZLE_STORAGE_ENGINE_PLUGIN,
1466
int ha_rollback_to_savepoint(THD *thd, SAVEPOINT *sv)
1149
int ha_rollback_to_savepoint(Session *session, SAVEPOINT *sv)
1469
THD_TRANS *trans= (thd->in_sub_stmt ? &thd->transaction.stmt :
1470
&thd->transaction.all);
1152
Session_TRANS *trans= &session->transaction.all;
1471
1153
Ha_trx_info *ha_info, *ha_info_next;
1473
1155
trans->no_2pc=0;
1577
static bool snapshot_handlerton(THD *thd, plugin_ref plugin, void *arg)
1258
static bool snapshot_handlerton(Session *session, plugin_ref plugin, void *arg)
1579
1260
handlerton *hton= plugin_data(plugin, handlerton *);
1580
1261
if (hton->state == SHOW_OPTION_YES &&
1581
1262
hton->start_consistent_snapshot)
1583
hton->start_consistent_snapshot(hton, thd);
1264
hton->start_consistent_snapshot(hton, session);
1584
1265
*((bool *)arg)= false;
1589
int ha_start_consistent_snapshot(THD *thd)
1270
int ha_start_consistent_snapshot(Session *session)
1591
1272
bool warn= true;
1593
plugin_foreach(thd, snapshot_handlerton, DRIZZLE_STORAGE_ENGINE_PLUGIN, &warn);
1274
plugin_foreach(session, snapshot_handlerton, DRIZZLE_STORAGE_ENGINE_PLUGIN, &warn);
1596
1277
Same idea as when one wants to CREATE TABLE in one engine which does not
1600
push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
1601
"This MySQL server does not support any "
1281
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
1282
"This Drizzle server does not support any "
1602
1283
"consistent-read capable storage engine");
1607
static bool flush_handlerton(THD *thd __attribute__((unused)),
1288
static bool flush_handlerton(Session *session __attribute__((unused)),
1608
1289
plugin_ref plugin,
1609
1290
void *arg __attribute__((unused)))
1611
1292
handlerton *hton= plugin_data(plugin, handlerton *);
1612
if (hton->state == SHOW_OPTION_YES && hton->flush_logs &&
1293
if (hton->state == SHOW_OPTION_YES && hton->flush_logs &&
1613
1294
hton->flush_logs(hton))
1661
1342
struct Ha_delete_table_error_handler: public Internal_error_handler
1664
virtual bool handle_error(uint sql_errno,
1345
virtual bool handle_error(uint32_t sql_errno,
1665
1346
const char *message,
1666
1347
DRIZZLE_ERROR::enum_warning_level level,
1668
1349
char buff[DRIZZLE_ERRMSG_SIZE];
1673
1354
Ha_delete_table_error_handler::
1674
handle_error(uint sql_errno __attribute__((unused)),
1355
handle_error(uint32_t sql_errno __attribute__((unused)),
1675
1356
const char *message,
1676
1357
DRIZZLE_ERROR::enum_warning_level level __attribute__((unused)),
1677
THD *thd __attribute__((unused)))
1358
Session *session __attribute__((unused)))
1679
1360
/* Grab the error message */
1680
strmake(buff, message, sizeof(buff)-1);
1361
strncpy(buff, message, sizeof(buff)-1);
1366
struct handlerton_delete_table_args {
1373
static bool deletetable_handlerton(Session *unused1 __attribute__((unused)),
1377
struct handlerton_delete_table_args *dtargs= (struct handlerton_delete_table_args *) args;
1379
Session *session= dtargs->session;
1380
const char *path= dtargs->path;
1383
char tmp_path[FN_REFLEN];
1385
if(dtargs->error!=ENOENT) /* already deleted table */
1388
handlerton *table_type= plugin_data(plugin, handlerton *);
1393
if(!(table_type->state == SHOW_OPTION_YES && table_type->create))
1396
if ((file= table_type->create(table_type, NULL, session->mem_root)))
1401
path= check_lowercase_names(file, path, tmp_path);
1402
int error= file->ha_delete_table(path);
1406
dtargs->error= error;
1408
delete dtargs->file;
1686
1417
This should return ENOENT if the file doesn't exists.
1687
1418
The .frm file will be deleted only if we return 0 or ENOENT
1689
int ha_delete_table(THD *thd, handlerton *table_type, const char *path,
1420
int ha_delete_table(Session *session, const char *path,
1690
1421
const char *db, const char *alias, bool generate_warning)
1693
char tmp_path[FN_REFLEN];
1696
1423
TABLE_SHARE dummy_share;
1426
struct handlerton_delete_table_args dtargs;
1427
dtargs.error= ENOENT;
1428
dtargs.session= session;
1432
plugin_foreach(NULL, deletetable_handlerton, DRIZZLE_STORAGE_ENGINE_PLUGIN,
1698
1435
memset(&dummy_table, 0, sizeof(dummy_table));
1699
1436
memset(&dummy_share, 0, sizeof(dummy_share));
1700
1437
dummy_table.s= &dummy_share;
1702
/* DB_TYPE_UNKNOWN is used in ALTER TABLE when renaming only .frm files */
1703
if (table_type == NULL ||
1704
! (file=get_new_handler((TABLE_SHARE*)0, thd->mem_root, table_type)))
1707
path= check_lowercase_names(file, path, tmp_path);
1708
if ((error= file->ha_delete_table(path)) && generate_warning)
1439
if (dtargs.error && generate_warning)
1711
1442
Because file->print_error() use my_error() to generate the error message
1724
1455
dummy_share.table_name.length= strlen(alias);
1725
1456
dummy_table.alias= alias;
1458
handler *file= dtargs.file;
1727
1459
file->change_table_ptr(&dummy_table, &dummy_share);
1729
thd->push_internal_handler(&ha_delete_table_error_handler);
1730
file->print_error(error, 0);
1461
session->push_internal_handler(&ha_delete_table_error_handler);
1462
file->print_error(dtargs.error, 0);
1732
thd->pop_internal_handler();
1464
session->pop_internal_handler();
1735
1467
XXX: should we convert *all* errors to warnings here?
1736
1468
What if the error is fatal?
1738
push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_ERROR, error,
1470
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_ERROR, dtargs.error,
1739
1471
ha_delete_table_error_handler.buff);
1477
return dtargs.error;
1745
1480
/****************************************************************************
1750
1485
handler *new_handler= get_new_handler(table->s, mem_root, table->s->db_type());
1752
1487
Allocate handler->ref here because otherwise ha_open will allocate it
1753
on this->table->mem_root and we will not be able to reclaim that memory
1488
on this->table->mem_root and we will not be able to reclaim that memory
1754
1489
when the clone handler object is destroyed.
1756
if (!(new_handler->ref= (uchar*) alloc_root(mem_root, ALIGN_SIZE(ref_length)*2)))
1491
if (!(new_handler->ref= (unsigned char*) alloc_root(mem_root, ALIGN_SIZE(ref_length)*2)))
1758
1493
if (new_handler && !new_handler->ha_open(table,
1759
1494
table->s->normalized_path.str,
1761
1496
HA_OPEN_IGNORE_IF_LOCKED))
1762
1497
return new_handler;
1501
int handler::ha_index_init(uint32_t idx, bool sorted)
1504
assert(inited==NONE);
1505
if (!(result= index_init(idx, sorted)))
1511
int handler::ha_index_end()
1513
assert(inited==INDEX);
1516
return(index_end());
1519
int handler::ha_rnd_init(bool scan)
1522
assert(inited==NONE || (inited==RND && scan));
1523
inited= (result= rnd_init(scan)) ? NONE: RND;
1527
int handler::ha_rnd_end()
1529
assert(inited==RND);
1534
int handler::ha_index_or_rnd_end()
1536
return inited == INDEX ? ha_index_end() : inited == RND ? ha_rnd_end() : 0;
1539
handler::Table_flags handler::ha_table_flags() const
1541
return cached_table_flags;
1544
void handler::ha_start_bulk_insert(ha_rows rows)
1546
estimation_rows_to_insert= rows;
1547
start_bulk_insert(rows);
1550
int handler::ha_end_bulk_insert()
1552
estimation_rows_to_insert= 0;
1553
return end_bulk_insert();
1556
void handler::change_table_ptr(Table *table_arg, TABLE_SHARE *share)
1562
const key_map *handler::keys_to_use_for_scanning()
1564
return &key_map_empty;
1567
bool handler::has_transactions()
1569
return (ha_table_flags() & HA_NO_TRANSACTIONS) == 0;
1768
1572
void handler::ha_statistic_increment(ulong SSV::*offset) const
1770
1574
status_var_increment(table->in_use->status_var.*offset);
1773
void **handler::ha_data(THD *thd) const
1775
return thd_ha_data(thd, ht);
1778
THD *handler::ha_thd(void) const
1780
assert(!table || !table->in_use || table->in_use == current_thd);
1781
return (table && table->in_use) ? table->in_use : current_thd;
1577
void **handler::ha_data(Session *session) const
1579
return session_ha_data(session, ht);
1582
Session *handler::ha_session(void) const
1584
assert(!table || !table->in_use || table->in_use == current_session);
1585
return (table && table->in_use) ? table->in_use : current_session;
1589
bool handler::is_fatal_error(int error, uint32_t flags)
1592
((flags & HA_CHECK_DUP_KEY) &&
1593
(error == HA_ERR_FOUND_DUPP_KEY ||
1594
error == HA_ERR_FOUND_DUPP_UNIQUE)))
1600
ha_rows handler::records() { return stats.records; }
1785
1603
Open database-handler.
2558
static bool update_frm_version(TABLE *table)
2560
char path[FN_REFLEN];
2565
No need to update frm version in case table was created or checked
2566
by server with the same version. This also ensures that we do not
2567
update frm version for temporary tables as this code doesn't support
2570
if (table->s->mysql_version == DRIZZLE_VERSION_ID)
2573
strxmov(path, table->s->normalized_path.str, reg_ext, NullS);
2575
if ((file= my_open(path, O_RDWR|O_BINARY, MYF(MY_WME))) >= 0)
2578
char *key= table->s->table_cache_key.str;
2579
uint key_length= table->s->table_cache_key.length;
2581
HASH_SEARCH_STATE state;
2583
int4store(version, DRIZZLE_VERSION_ID);
2585
if (pwrite(file, (uchar*)version, 4, 51L) == 0)
2591
for (entry=(TABLE*) hash_first(&open_cache,(uchar*) key,key_length, &state);
2593
entry= (TABLE*) hash_next(&open_cache,(uchar*) key,key_length, &state))
2594
entry->s->mysql_version= DRIZZLE_VERSION_ID;
2598
VOID(my_close(file,MYF(MY_WME)));
2606
2371
key if error because of duplicated keys
2608
uint handler::get_dup_key(int error)
2373
uint32_t handler::get_dup_key(int error)
2610
2375
table->file->errkey = (uint) -1;
2611
2376
if (error == HA_ERR_FOUND_DUPP_KEY || error == HA_ERR_FOREIGN_DUPLICATE_KEY ||
3012
2776
is an optimization hint that storage engine is free to ignore.
3013
2777
So, let's commit an open transaction (if any) now.
3015
if (!(error= ha_commit_trans(thd, 0)))
3016
error= end_trans(thd, COMMIT);
2779
if (!(error= ha_commit_trans(session, 0)))
2780
error= end_trans(session, COMMIT);
3021
int handler::index_next_same(uchar *buf, const uchar *key, uint keylen)
2785
int handler::index_next_same(unsigned char *buf, const unsigned char *key, uint32_t keylen)
3024
2788
if (!(error=index_next(buf)))
3026
2790
my_ptrdiff_t ptrdiff= buf - table->record[0];
3027
uchar *save_record_0= NULL;
2791
unsigned char *save_record_0= NULL;
3028
2792
KEY *key_info= NULL;
3029
2793
KEY_PART_INFO *key_part;
3030
2794
KEY_PART_INFO *key_part_end= NULL;
3084
int ha_create_table(THD *thd, const char *path,
2848
int ha_create_table(Session *session, const char *path,
3085
2849
const char *db, const char *table_name,
3086
2850
HA_CREATE_INFO *create_info,
3087
2851
bool update_create_info)
3091
2855
char name_buff[FN_REFLEN];
3092
2856
const char *name;
3093
2857
TABLE_SHARE share;
3095
init_tmp_table_share(thd, &share, db, 0, table_name, path);
3096
if (open_table_def(thd, &share, 0) ||
3097
open_table_from_share(thd, &share, "", 0, (uint) READ_ALL, 0, &table,
2859
init_tmp_table_share(session, &share, db, 0, table_name, path);
2860
if (open_table_def(session, &share, 0) ||
2861
open_table_from_share(session, &share, "", 0, (uint) READ_ALL, 0, &table,
3101
2865
if (update_create_info)
3102
update_create_info_from_table(create_info, &table);
2866
table.updateCreateInfo(create_info);
3104
2868
name= check_lowercase_names(table.file, share.path.str, name_buff);
3106
2870
error= table.file->ha_create(name, &table, create_info);
3107
VOID(closefrm(&table, 0));
2871
closefrm(&table, 0);
3110
strxmov(name_buff, db, ".", table_name, NullS);
2874
sprintf(name_buff,"%s.%s",db,table_name);
3111
2875
my_error(ER_CANT_CREATE_TABLE, MYF(ME_BELL+ME_WAITTANG), name_buff, error);
3115
2879
return(error != 0);
3119
Try to discover table from engine.
3122
If found, write the frm file to disk.
3125
-1 Table did not exists
3129
> 0 Error, table existed but could not be created
3131
int ha_create_table_from_engine(THD* thd, const char *db, const char *name)
3136
char path[FN_REFLEN];
3137
HA_CREATE_INFO create_info;
3141
memset(&create_info, 0, sizeof(create_info));
3142
if ((error= ha_discover(thd, db, name, &frmblob, &frmlen)))
3144
/* Table could not be discovered and thus not created */
3149
Table exists in handler and could be discovered
3150
frmblob and frmlen are set, write the frm to disk
3153
build_table_filename(path, FN_REFLEN-1, db, name, "", 0);
3154
// Save the frm file
3155
error= writefrm(path, frmblob, frmlen);
3156
my_free(frmblob, MYF(0));
3160
init_tmp_table_share(thd, &share, db, 0, name, path);
3161
if (open_table_def(thd, &share, 0))
3165
if (open_table_from_share(thd, &share, "" ,0, 0, 0, &table, OTM_OPEN))
3167
free_table_share(&share);
3171
update_create_info_from_table(&create_info, &table);
3172
create_info.table_options|= HA_OPTION_CREATE_FROM_ENGINE;
3174
check_lowercase_names(table.file, path, path);
3175
error=table.file->ha_create(path, &table, &create_info);
3176
VOID(closefrm(&table, 1));
3181
2882
void st_ha_check_opt::init()
3183
2884
flags= sql_flags= 0;
3184
sort_buffer_size = current_thd->variables.myisam_sort_buff_size;
2885
sort_buffer_size = current_session->variables.myisam_sort_buff_size;
3279
Try to discover one table from handler(s).
3282
-1 Table did not exists
3284
0 OK. In this case *frmblob and *frmlen are set
3286
>0 error. frmblob and frmlen may not be set
3288
struct st_discover_args
3296
static bool discover_handlerton(THD *thd, plugin_ref plugin,
3299
st_discover_args *vargs= (st_discover_args *)arg;
3300
handlerton *hton= plugin_data(plugin, handlerton *);
3301
if (hton->state == SHOW_OPTION_YES && hton->discover &&
3302
(!(hton->discover(hton, thd, vargs->db, vargs->name,
3310
int ha_discover(THD *thd, const char *db, const char *name,
3311
uchar **frmblob, size_t *frmlen)
3313
int error= -1; // Table does not exist in any handler
3314
st_discover_args args= {db, name, frmblob, frmlen};
3316
if (is_prefix(name,tmp_file_prefix)) /* skip temporary tables */
3319
if (plugin_foreach(thd, discover_handlerton,
3320
DRIZZLE_STORAGE_ENGINE_PLUGIN, &args))
3324
status_var_increment(thd->status_var.ha_discover_count);
3330
2979
Call this function in order to give the handler the possiblity
3331
2980
to ask engine if there are any new tables that should be written to disk
3365
3015
int err= HA_ERR_NO_SUCH_TABLE;
3367
3017
if (hton->state == SHOW_OPTION_YES && hton->table_exists_in_engine)
3368
err = hton->table_exists_in_engine(hton, thd, vargs->db, vargs->name);
3018
err = hton->table_exists_in_engine(hton, session, vargs->db, vargs->name);
3370
3020
vargs->err = err;
3371
3021
if (vargs->err == HA_ERR_TABLE_EXIST)
3377
int ha_table_exists_in_engine(THD* thd, const char* db, const char* name)
3030
int ha_table_exists_in_engine(Session* session,
3031
const char* db, const char* name,
3379
st_table_exists_in_engine_args args= {db, name, HA_ERR_NO_SUCH_TABLE};
3380
plugin_foreach(thd, table_exists_in_engine_handlerton,
3034
st_table_exists_in_engine_args args= {db, name, HA_ERR_NO_SUCH_TABLE, NULL};
3035
plugin_foreach(session, table_exists_in_engine_handlerton,
3381
3036
DRIZZLE_STORAGE_ENGINE_PLUGIN, &args);
3038
if(args.err==HA_ERR_NO_SUCH_TABLE)
3040
/* Default way of knowing if a table exists. (checking .frm exists) */
3042
char path[FN_REFLEN];
3043
build_table_filename(path, sizeof(path),
3044
db, name, ".frm", 0);
3045
if (!access(path, F_OK))
3046
args.err= HA_ERR_TABLE_EXIST;
3048
args.err= HA_ERR_NO_SUCH_TABLE;
3050
enum legacy_db_type table_type;
3051
if(args.err==HA_ERR_TABLE_EXIST && mysql_frm_type(path, &table_type)==0)
3053
args.hton= ha_resolve_by_legacy_type(session, table_type);
3382
3060
return(args.err);
3453
handler::multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq,
3131
handler::multi_range_read_info_const(uint32_t keyno, RANGE_SEQ_IF *seq,
3454
3132
void *seq_init_param,
3455
uint n_ranges_arg __attribute__((unused)),
3456
uint *bufsz, uint *flags, COST_VECT *cost)
3133
uint32_t n_ranges_arg __attribute__((unused)),
3134
uint32_t *bufsz, uint32_t *flags, COST_VECT *cost)
3458
3136
KEY_MULTI_RANGE range;
3459
3137
range_seq_t seq_it;
3460
3138
ha_rows rows, total_rows= 0;
3462
THD *thd= current_thd;
3139
uint32_t n_ranges=0;
3140
Session *session= current_session;
3464
3142
/* Default MRR implementation doesn't need buffer */
3467
3145
seq_it= seq->init(seq_init_param, n_ranges, *flags);
3468
3146
while (!seq->next(seq_it, &range))
3470
if (unlikely(thd->killed != 0))
3148
if (unlikely(session->killed != 0))
3471
3149
return HA_POS_ERROR;
3474
3152
key_range *min_endp, *max_endp;
3907
3585
DS-MRR implementation: multi_range_read_info() function
3909
int DsMrr_impl::dsmrr_info(uint keyno, uint n_ranges, uint rows, uint *bufsz,
3910
uint *flags, COST_VECT *cost)
3587
int DsMrr_impl::dsmrr_info(uint32_t keyno, uint32_t n_ranges, uint32_t rows, uint32_t *bufsz,
3588
uint32_t *flags, COST_VECT *cost)
3913
uint def_flags= *flags;
3914
uint def_bufsz= *bufsz;
3591
uint32_t def_flags= *flags;
3592
uint32_t def_bufsz= *bufsz;
3916
3594
/* Get cost/flags/mem_usage of default MRR implementation */
3917
3595
res= h->handler::multi_range_read_info(keyno, n_ranges, rows, &def_bufsz,
3918
3596
&def_flags, cost);
3921
if ((*flags & HA_MRR_USE_DEFAULT_IMPL) ||
3599
if ((*flags & HA_MRR_USE_DEFAULT_IMPL) ||
3922
3600
choose_mrr_impl(keyno, rows, &def_flags, &def_bufsz, cost))
3924
3602
/* Default implementation is choosen */
3933
3611
DS-MRR Implementation: multi_range_read_info_const() function
3936
ha_rows DsMrr_impl::dsmrr_info_const(uint keyno, RANGE_SEQ_IF *seq,
3937
void *seq_init_param, uint n_ranges,
3938
uint *bufsz, uint *flags, COST_VECT *cost)
3614
ha_rows DsMrr_impl::dsmrr_info_const(uint32_t keyno, RANGE_SEQ_IF *seq,
3615
void *seq_init_param, uint32_t n_ranges,
3616
uint32_t *bufsz, uint32_t *flags, COST_VECT *cost)
3941
uint def_flags= *flags;
3942
uint def_bufsz= *bufsz;
3619
uint32_t def_flags= *flags;
3620
uint32_t def_bufsz= *bufsz;
3943
3621
/* Get cost/flags/mem_usage of default MRR implementation */
3944
3622
rows= h->handler::multi_range_read_info_const(keyno, seq, seq_init_param,
3945
n_ranges, &def_bufsz,
3623
n_ranges, &def_bufsz,
3946
3624
&def_flags, cost);
3947
3625
if (rows == HA_POS_ERROR)
4023
3701
@retval false DS-MRR implementation should be used
4026
bool DsMrr_impl::choose_mrr_impl(uint keyno, ha_rows rows, uint *flags,
4027
uint *bufsz, COST_VECT *cost)
3704
bool DsMrr_impl::choose_mrr_impl(uint32_t keyno, ha_rows rows, uint32_t *flags,
3705
uint32_t *bufsz, COST_VECT *cost)
4029
3707
COST_VECT dsmrr_cost;
4031
THD *thd= current_thd;
4032
if ((thd->variables.optimizer_use_mrr == 2) ||
3709
Session *session= current_session;
3710
if ((session->variables.optimizer_use_mrr == 2) ||
4033
3711
(*flags & HA_MRR_INDEX_ONLY) || (*flags & HA_MRR_SORTED) ||
4034
(keyno == table->s->primary_key &&
4035
h->primary_key_is_clustered()) ||
3712
(keyno == table->s->primary_key &&
3713
h->primary_key_is_clustered()) ||
4036
3714
key_uses_partial_cols(keyno))
4038
3716
/* Use the default implementation */
4039
3717
*flags |= HA_MRR_USE_DEFAULT_IMPL;
4043
uint add_len= table->key_info[keyno].key_length + h->ref_length;
3721
uint32_t add_len= table->key_info[keyno].key_length + h->ref_length;
4044
3722
*bufsz -= add_len;
4045
3723
if (get_disk_sweep_mrr_cost(keyno, rows, *flags, bufsz, &dsmrr_cost))
4047
3725
*bufsz += add_len;
4049
3727
bool force_dsmrr;
4051
3729
If @@optimizer_use_mrr==force, then set cost of DS-MRR to be minimum of
4052
3730
DS-MRR and Default implementations cost. This allows one to force use of
4053
3731
DS-MRR whenever it is applicable without affecting other cost-based
4056
if ((force_dsmrr= (thd->variables.optimizer_use_mrr == 1)) &&
3734
if ((force_dsmrr= (session->variables.optimizer_use_mrr == 1)) &&
4057
3735
dsmrr_cost.total_cost() > cost->total_cost())
4058
3736
dsmrr_cost= *cost;
4468
static bool stat_print(THD *thd, const char *type, uint type_len,
4469
const char *file, uint file_len,
4470
const char *status, uint status_len)
4147
static bool stat_print(Session *session, const char *type, uint32_t type_len,
4148
const char *file, uint32_t file_len,
4149
const char *status, uint32_t status_len)
4472
Protocol *protocol= thd->protocol;
4151
Protocol *protocol= session->protocol;
4473
4152
protocol->prepare_for_resend();
4474
4153
protocol->store(type, type_len, system_charset_info);
4475
4154
protocol->store(file, file_len, system_charset_info);
4514
4193
- table is not mysql.event
4517
static bool check_table_binlog_row_based(THD *thd, TABLE *table)
4519
if (table->s->cached_row_logging_check == -1)
4521
int const check(table->s->tmp_table == NO_TMP_TABLE &&
4522
binlog_filter->db_ok(table->s->db.str));
4523
table->s->cached_row_logging_check= check;
4526
assert(table->s->cached_row_logging_check == 0 ||
4527
table->s->cached_row_logging_check == 1);
4529
return (thd->current_stmt_binlog_row_based &&
4530
table->s->cached_row_logging_check &&
4531
(thd->options & OPTION_BIN_LOG) &&
4532
mysql_bin_log.is_open());
4537
Write table maps for all (manually or automatically) locked tables
4540
This function will generate and write table maps for all tables
4541
that are locked by the thread 'thd'. Either manually locked
4542
(stored in THD::locked_tables) and automatically locked (stored
4543
in THD::lock) are considered.
4545
@param thd Pointer to THD structure
4548
@retval 1 Failed to write all table maps
4555
static int write_locked_table_maps(THD *thd)
4557
if (thd->get_binlog_table_maps() == 0)
4559
DRIZZLE_LOCK *locks[3];
4560
locks[0]= thd->extra_lock;
4561
locks[1]= thd->lock;
4562
locks[2]= thd->locked_tables;
4563
for (uint i= 0 ; i < sizeof(locks)/sizeof(*locks) ; ++i )
4565
DRIZZLE_LOCK const *const lock= locks[i];
4569
TABLE **const end_ptr= lock->table + lock->table_count;
4570
for (TABLE **table_ptr= lock->table ;
4571
table_ptr != end_ptr ;
4574
TABLE *const table= *table_ptr;
4575
if (table->current_lock == F_WRLCK &&
4576
check_table_binlog_row_based(thd, table))
4578
int const has_trans= table->file->has_transactions();
4579
int const error= thd->binlog_write_table_map(table, has_trans);
4581
If an error occurs, it is the responsibility of the caller to
4582
roll back the transaction.
4584
if (unlikely(error))
4594
typedef bool Log_func(THD*, TABLE*, bool, const uchar*, const uchar*);
4596
static int binlog_log_row(TABLE* table,
4597
const uchar *before_record,
4598
const uchar *after_record,
4601
if (table->no_replicate)
4604
THD *const thd= table->in_use;
4606
if (check_table_binlog_row_based(thd, table))
4196
static bool binlog_log_row(Table* table,
4197
const unsigned char *before_record,
4198
const unsigned char *after_record)
4201
Session *const session= table->in_use;
4203
if (table->no_replicate == false)
4206
error= replicator_session_init(session);
4208
switch (session->lex->sql_command)
4210
case SQLCOM_REPLACE:
4212
case SQLCOM_REPLACE_SELECT:
4213
case SQLCOM_INSERT_SELECT:
4214
case SQLCOM_CREATE_TABLE:
4215
error= replicator_write_row(session, table);
4219
case SQLCOM_UPDATE_MULTI:
4220
error= replicator_update_row(session, table, before_record, after_record);
4224
case SQLCOM_DELETE_MULTI:
4225
error= replicator_delete_row(session, table);
4609
If there are no table maps written to the binary log, this is
4610
the first row handled in this statement. In that case, we need
4611
to write table maps for all locked tables to the binary log.
4229
For everything else we ignore the event (since it just involves a temp table)
4613
if (likely(!(error= write_locked_table_maps(thd))))
4615
bool const has_trans= table->file->has_transactions();
4616
error= (*log_func)(thd, table, has_trans, before_record, after_record);
4619
return error ? HA_ERR_RBR_LOGGING_FAILED : 0;
4622
int handler::ha_external_lock(THD *thd, int lock_type)
4238
int handler::ha_external_lock(Session *session, int lock_type)
4625
4241
Whether this is lock or unlock, this should be true, and is to verify that
4665
int handler::ha_write_row(uchar *buf)
4281
int handler::ha_write_row(unsigned char *buf)
4668
Log_func *log_func= Write_rows_log_event::binlog_row_logging_function;
4669
4284
DRIZZLE_INSERT_ROW_START();
4671
4286
mark_trx_read_write();
4673
4288
if (unlikely(error= write_row(buf)))
4675
if (unlikely(error= binlog_log_row(table, 0, buf, log_func)))
4676
return(error); /* purecov: inspected */
4291
if (unlikely(binlog_log_row(table, 0, buf)))
4292
return HA_ERR_RBR_LOGGING_FAILED; /* purecov: inspected */
4677
4294
DRIZZLE_INSERT_ROW_END();
4682
int handler::ha_update_row(const uchar *old_data, uchar *new_data)
4299
int handler::ha_update_row(const unsigned char *old_data, unsigned char *new_data)
4685
Log_func *log_func= Update_rows_log_event::binlog_row_logging_function;
4688
4304
Some storage engines require that the new record is in record[0]
4695
4311
if (unlikely(error= update_row(old_data, new_data)))
4697
if (unlikely(error= binlog_log_row(table, old_data, new_data, log_func)))
4314
if (unlikely(binlog_log_row(table, old_data, new_data)))
4315
return HA_ERR_RBR_LOGGING_FAILED;
4702
int handler::ha_delete_row(const uchar *buf)
4320
int handler::ha_delete_row(const unsigned char *buf)
4705
Log_func *log_func= Delete_rows_log_event::binlog_row_logging_function;
4707
4324
mark_trx_read_write();
4709
4326
if (unlikely(error= delete_row(buf)))
4711
if (unlikely(error= binlog_log_row(table, buf, 0, log_func)))
4329
if (unlikely(binlog_log_row(table, buf, 0)))
4330
return HA_ERR_RBR_LOGGING_FAILED;