19
19
Handler-calling-functions
22
#ifdef USE_PRAGMA_IMPLEMENTATION
23
#pragma implementation // gcc: Class implementation
26
#include "mysql_priv.h"
22
#include <drizzled/server_includes.h>
27
23
#include "rpl_filter.h"
28
#include <myisampack.h>
24
#include <drizzled/drizzled_error_messages.h>
32
27
While we have legacy_db_type, we have this array to
40
35
#define BITMAP_STACKBUF_SIZE (128/8)
42
KEY_CREATE_INFO default_key_create_info= { HA_KEY_ALG_UNDEF, 0, {NullS,0}, {NullS,0} };
37
KEY_CREATE_INFO default_key_create_info= { HA_KEY_ALG_UNDEF, 0, {NULL,0}, {NULL,0} };
44
39
/* number of entries in handlertons[] */
46
41
/* number of storage engines (from handlertons[]) that support 2pc */
47
ulong total_ha_2pc= 0;
42
uint32_t total_ha_2pc= 0;
48
43
/* size of savepoint storage area (see ha_init) */
49
ulong savepoint_alloc_size= 0;
44
uint32_t savepoint_alloc_size= 0;
51
46
static const LEX_STRING sys_table_aliases[]=
53
48
{ C_STRING_WITH_LEN("INNOBASE") }, { C_STRING_WITH_LEN("INNODB") },
54
49
{ C_STRING_WITH_LEN("HEAP") }, { C_STRING_WITH_LEN("MEMORY") },
58
53
const char *ha_row_type[] = {
62
57
const char *tx_isolation_names[] =
63
58
{ "READ-UNCOMMITTED", "READ-COMMITTED", "REPEATABLE-READ", "SERIALIZABLE",
65
60
TYPELIB tx_isolation_typelib= {array_elements(tx_isolation_names)-1,"",
66
61
tx_isolation_names, NULL};
68
63
static TYPELIB known_extensions= {0,"known_exts", NULL, NULL};
69
uint known_extensions_id= 0;
64
uint32_t known_extensions_id= 0;
115
110
/* my_strnncoll is a macro and gcc doesn't do early expansion of macro */
116
if (thd && !my_charset_latin1.coll->strnncoll(&my_charset_latin1,
117
(const uchar *)name->str, name->length,
118
(const uchar *)STRING_WITH_LEN("DEFAULT"), 0))
111
if (thd && !my_charset_utf8_general_ci.coll->strnncoll(&my_charset_utf8_general_ci,
112
(const unsigned char *)name->str, name->length,
113
(const unsigned char *)STRING_WITH_LEN("DEFAULT"), 0))
119
114
return ha_default_plugin(thd);
121
if ((plugin= my_plugin_lock_by_name(thd, name, MYSQL_STORAGE_ENGINE_PLUGIN)))
116
if ((plugin= my_plugin_lock_by_name(thd, name, DRIZZLE_STORAGE_ENGINE_PLUGIN)))
123
118
handlerton *hton= plugin_data(plugin, handlerton *);
124
119
if (!(hton->flags & HTON_NOT_USER_SELECTABLE))
136
131
for (table_alias= sys_table_aliases; table_alias->str; table_alias+= 2)
138
if (!my_strnncoll(&my_charset_latin1,
139
(const uchar *)name->str, name->length,
140
(const uchar *)table_alias->str, table_alias->length))
133
if (!my_strnncoll(&my_charset_utf8_general_ci,
134
(const unsigned char *)name->str, name->length,
135
(const unsigned char *)table_alias->str, table_alias->length))
142
137
name= table_alias + 1;
216
200
handlerton *db_type)
219
DBUG_ENTER("get_new_handler");
220
DBUG_PRINT("enter", ("alloc: 0x%lx", (long) alloc));
222
204
if (db_type && db_type->state == SHOW_OPTION_YES && db_type->create)
224
206
if ((file= db_type->create(db_type, share, alloc)))
229
211
Try the default table type
230
212
Here the call to current_thd() is ok as we call this function a lot of
231
213
times but we enter this branch very seldom.
233
DBUG_RETURN(get_new_handler(share, alloc, ha_default_handlerton(current_thd)));
215
return(get_new_handler(share, alloc, ha_default_handlerton(current_thd)));
317
299
/* Allocate a pointer array for the error message strings. */
318
300
if (! (errmsgs= my_error_unregister(HA_ERR_FIRST, HA_ERR_LAST)))
320
my_free((uchar*) errmsgs, MYF(0));
302
free((unsigned char*) errmsgs);
342
hton->panic(hton, HA_PANIC_CLOSE);
344
if (plugin->plugin->deinit)
347
Today we have no defined/special behavior for uninstalling
350
DBUG_PRINT("info", ("Deinitializing plugin: '%s'", plugin->name.str));
351
if (plugin->plugin->deinit(NULL))
353
DBUG_PRINT("warning", ("Plugin '%s' deinit function returned error.",
358
my_free((uchar*)hton, MYF(0));
322
if (hton && plugin->plugin->deinit)
323
(void)plugin->plugin->deinit(hton);
325
free((unsigned char*)hton);
364
331
int ha_initialize_handlerton(st_plugin_int *plugin)
366
333
handlerton *hton;
367
DBUG_ENTER("ha_initialize_handlerton");
368
DBUG_PRINT("plugin", ("initialize plugin: '%s'", plugin->name.str));
370
335
hton= (handlerton *)my_malloc(sizeof(handlerton),
371
336
MYF(MY_WME | MY_ZEROFILL));
376
341
structure. Apparently get_backup_engine was not NULL even though it was
379
bzero(hton, sizeof(hton));
344
memset(hton, 0, sizeof(hton));
380
345
/* Historical Requirement */
381
346
plugin->data= hton; // shortcut for the future
382
347
if (plugin->plugin->init)
384
349
if (plugin->plugin->init(hton))
386
sql_print_error("Plugin '%s' init function returned error.",
351
sql_print_error(_("Plugin '%s' init function returned error."),
387
352
plugin->name.str);
412
377
if (idx == (int) DB_TYPE_DEFAULT)
414
sql_print_warning("Too many storage engines!");
379
sql_print_warning(_("Too many storage engines!"));
417
382
if (hton->db_type != DB_TYPE_UNKNOWN)
418
sql_print_warning("Storage engine '%s' has conflicting typecode. "
419
"Assigning value %d.", plugin->plugin->name, idx);
383
sql_print_warning(_("Storage engine '%s' has conflicting typecode. "
384
"Assigning value %d."), plugin->plugin->name, idx);
420
385
hton->db_type= (enum legacy_db_type) idx;
422
387
installed_htons[hton->db_type]= hton;
440
405
"memory" hton which will be configurable longterm. We should be able to
441
406
remove partition and myisammrg.
443
switch (hton->db_type) {
408
if (strcmp(plugin->plugin->name, "MEMORY") == 0)
411
if (strcmp(plugin->plugin->name, "MyISAM") == 0)
448
412
myisam_hton= hton;
462
DBUG_ENTER("ha_init");
464
DBUG_ASSERT(total_ha < MAX_HA);
423
assert(total_ha < MAX_HA);
466
425
Check if there is a transaction-capable storage engine besides the
467
426
binary log (which is considered a transaction-capable storage engine in
468
427
counting total_ha)
470
opt_using_transactions= total_ha>(ulong)opt_bin_log;
429
opt_using_transactions= total_ha>(uint32_t)opt_bin_log;
471
430
savepoint_alloc_size+= sizeof(SAVEPOINT);
478
DBUG_ENTER("ha_end");
482
439
This should be eventualy based on the graceful shutdown flag.
486
443
if (ha_finish_errors())
492
static my_bool dropdb_handlerton(THD *unused1, plugin_ref plugin,
449
static bool dropdb_handlerton(THD *unused1 __attribute__((unused)),
495
453
handlerton *hton= plugin_data(plugin, handlerton *);
496
454
if (hton->state == SHOW_OPTION_YES && hton->drop_database)
497
455
hton->drop_database(hton, (char *)path);
502
460
void ha_drop_database(char* path)
504
plugin_foreach(NULL, dropdb_handlerton, MYSQL_STORAGE_ENGINE_PLUGIN, path);
462
plugin_foreach(NULL, dropdb_handlerton, DRIZZLE_STORAGE_ENGINE_PLUGIN, path);
508
static my_bool closecon_handlerton(THD *thd, plugin_ref plugin,
466
static bool closecon_handlerton(THD *thd, plugin_ref plugin,
467
void *unused __attribute__((unused)))
511
469
handlerton *hton= plugin_data(plugin, handlerton *);
527
485
void ha_close_connection(THD* thd)
529
plugin_foreach(thd, closecon_handlerton, MYSQL_STORAGE_ENGINE_PLUGIN, 0);
487
plugin_foreach(thd, closecon_handlerton, DRIZZLE_STORAGE_ENGINE_PLUGIN, 0);
532
490
/* ========================================================================
802
760
to maintain atomicity: if CREATE TABLE .. SELECT failed,
803
761
the newly created table is deleted.
804
762
In addition, some DDL statements issue interim transaction
805
commits: e.g. ALTER TABLE issues a commit after data is copied
763
commits: e.g. ALTER Table issues a commit after data is copied
806
764
from the original table to the internal temporary table. Other
807
765
statements, e.g. CREATE TABLE ... SELECT do not always commit
809
767
And finally there is a group of DDL statements such as
810
RENAME/DROP TABLE that doesn't start a new transaction
768
RENAME/DROP Table that doesn't start a new transaction
811
769
and doesn't commit.
813
771
This diversity makes it hard to say what will happen if
853
809
ha_info= thd->ha_data[ht_arg->slot].ha_info + static_cast<unsigned>(all);
855
811
if (ha_info->is_started())
856
DBUG_VOID_RETURN; /* already registered, return */
812
return; /* already registered, return */
858
814
ha_info->register_ha(trans, ht_arg);
898
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
853
push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
899
854
ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
900
855
ha_resolve_storage_engine_name(ht));
911
866
As a side effect, propagates the read-only/read-write flags
912
867
of the statement transaction to its enclosing normal transaction.
914
@retval TRUE we must run a two-phase commit. Returned
869
@retval true we must run a two-phase commit. Returned
915
870
if we have at least two engines with read-write changes.
916
@retval FALSE Don't need two-phase commit. Even if we have two
871
@retval false Don't need two-phase commit. Even if we have two
917
872
transactional engines, we can run two independent
918
873
commits if changes in one of the engines are read-only.
937
892
Ha_trx_info *ha_info_all= &thd->ha_data[ha_info->ht()->slot].ha_info[1];
938
DBUG_ASSERT(ha_info != ha_info_all);
893
assert(ha_info != ha_info_all);
940
895
Merge read-only/read-write information about statement
941
896
transaction to its enclosing normal transaction. Do this
943
898
that ha_info_all is registered in thd->transaction.all.
944
899
Since otherwise we only clutter the normal transaction flags.
946
if (ha_info_all->is_started()) /* FALSE if autocommit. */
901
if (ha_info_all->is_started()) /* false if autocommit. */
947
902
ha_info_all->coalesce_trx_with(ha_info);
949
904
else if (rw_ha_count > 1)
985
940
bool is_real_trans= all || thd->transaction.all.ha_list == 0;
986
941
Ha_trx_info *ha_info= trans->ha_list;
987
942
my_xid xid= thd->transaction.xid_state.xid.get_my_xid();
988
DBUG_ENTER("ha_commit_trans");
991
945
We must not commit the normal transaction if a statement
993
947
flags will not get propagated to its normal transaction's
996
DBUG_ASSERT(thd->transaction.stmt.ha_list == NULL ||
950
assert(thd->transaction.stmt.ha_list == NULL ||
997
951
trans == &thd->transaction.stmt);
999
if (thd->in_sub_stmt)
1002
Since we don't support nested statement transactions in 5.0,
1003
we can't commit or rollback stmt transactions while we are inside
1004
stored functions or triggers. So we simply do nothing now.
1005
TODO: This should be fixed in later ( >= 5.1) releases.
1010
We assume that all statements which commit or rollback main transaction
1011
are prohibited inside of stored functions or triggers. So they should
1012
bail out with error even before ha_commit_trans() call. To be 100% safe
1013
let us throw error in non-debug builds.
1016
my_error(ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0));
1064
998
status_var_increment(thd->status_var.ha_prepare_count);
1066
DBUG_EXECUTE_IF("crash_commit_after_prepare", abort(););
1067
1000
if (error || (is_real_trans && xid &&
1068
1001
(error= !(cookie= tc_log->log_xid(thd, xid)))))
1074
DBUG_EXECUTE_IF("crash_commit_after_log", abort(););
1076
1008
error=ha_commit_one_phase(thd, all) ? (cookie ? 2 : 1) : 0;
1077
DBUG_EXECUTE_IF("crash_commit_before_unlog", abort(););
1079
1010
tc_log->unlog(cookie, xid);
1080
DBUG_EXECUTE_IF("crash_commit_after", abort(););
1082
1012
if (is_real_trans)
1083
1013
start_waiting_global_read_lock(thd);
1095
1025
THD_TRANS *trans=all ? &thd->transaction.all : &thd->transaction.stmt;
1096
1026
bool is_real_trans=all || thd->transaction.all.ha_list == 0;
1097
1027
Ha_trx_info *ha_info= trans->ha_list, *ha_info_next;
1098
DBUG_ENTER("ha_commit_one_phase");
1101
1030
for (; ha_info; ha_info= ha_info_next)
1131
1060
THD_TRANS *trans=all ? &thd->transaction.all : &thd->transaction.stmt;
1132
1061
Ha_trx_info *ha_info= trans->ha_list, *ha_info_next;
1133
1062
bool is_real_trans=all || thd->transaction.all.ha_list == 0;
1134
DBUG_ENTER("ha_rollback_trans");
1137
1065
We must not rollback the normal transaction if a statement
1138
1066
transaction is pending.
1140
DBUG_ASSERT(thd->transaction.stmt.ha_list == NULL ||
1068
assert(thd->transaction.stmt.ha_list == NULL ||
1141
1069
trans == &thd->transaction.stmt);
1143
if (thd->in_sub_stmt)
1146
If we are inside stored function or trigger we should not commit or
1147
rollback current statement transaction. See comment in ha_commit_trans()
1148
call for more information.
1153
my_error(ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0));
1158
1073
for (; ha_info; ha_info= ha_info_next)
1193
1108
if (is_real_trans && thd->transaction.all.modified_non_trans_table &&
1194
1109
!thd->slave_thread && thd->killed != THD::KILL_CONNECTION)
1195
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
1110
push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
1196
1111
ER_WARNING_NOT_COMPLETE_ROLLBACK,
1197
1112
ER(ER_WARNING_NOT_COMPLETE_ROLLBACK));
1224
1138
(void) ha_rollback_trans(thd, 0);
1225
if (thd->transaction_rollback_request && !thd->in_sub_stmt)
1139
if (thd->transaction_rollback_request)
1226
1140
(void) ha_rollback(thd);
1229
1143
thd->variables.tx_isolation=thd->session_tx_isolation;
1240
static my_bool xacommit_handlerton(THD *unused1, plugin_ref plugin,
1154
static bool xacommit_handlerton(THD *unused1 __attribute__((unused)),
1243
1158
handlerton *hton= plugin_data(plugin, handlerton *);
1244
1159
if (hton->state == SHOW_OPTION_YES && hton->recover)
1246
1161
hton->commit_by_xid(hton, ((struct xahton_st *)arg)->xid);
1247
1162
((struct xahton_st *)arg)->result= 0;
1252
static my_bool xarollback_handlerton(THD *unused1, plugin_ref plugin,
1167
static bool xarollback_handlerton(THD *unused1 __attribute__((unused)),
1255
1171
handlerton *hton= plugin_data(plugin, handlerton *);
1256
1172
if (hton->state == SHOW_OPTION_YES && hton->recover)
1269
1185
xaop.result= 1;
1271
1187
plugin_foreach(NULL, commit ? xacommit_handlerton : xarollback_handlerton,
1272
MYSQL_STORAGE_ENGINE_PLUGIN, &xaop);
1188
DRIZZLE_STORAGE_ENGINE_PLUGIN, &xaop);
1274
1190
return xaop.result;
1281
This does not need to be multi-byte safe or anything
1283
static char* xid_to_str(char *buf, XID *xid)
1288
for (i=0; i < xid->gtrid_length+xid->bqual_length; i++)
1290
uchar c=(uchar)xid->data[i];
1291
/* is_next_dig is set if next character is a number */
1292
bool is_next_dig= FALSE;
1293
if (i < XIDDATASIZE)
1295
char ch= xid->data[i+1];
1296
is_next_dig= (ch >= '0' && ch <='9');
1298
if (i == xid->gtrid_length)
1301
if (xid->bqual_length)
1307
if (c < 32 || c > 126)
1311
If next character is a number, write current character with
1312
3 octal numbers to ensure that the next number is not seen
1313
as part of the octal number
1315
if (c > 077 || is_next_dig)
1316
*s++=_dig_vec_lower[c >> 6];
1317
if (c > 007 || is_next_dig)
1318
*s++=_dig_vec_lower[(c >> 3) & 7];
1319
*s++=_dig_vec_lower[c & 7];
1323
if (c == '\'' || c == '\\')
1335
1194
recover() step of xa.
1358
static my_bool xarecover_handlerton(THD *unused, plugin_ref plugin,
1217
static bool xarecover_handlerton(THD *unused __attribute__((unused)),
1361
1221
handlerton *hton= plugin_data(plugin, handlerton *);
1362
1222
struct xarecover_st *info= (struct xarecover_st *) arg;
1367
1227
while ((got= hton->recover(hton, info->list, info->len)) > 0 )
1369
sql_print_information("Found %d prepared transaction(s) in %s",
1229
sql_print_information(_("Found %d prepared transaction(s) in %s"),
1370
1230
got, ha_resolve_storage_engine_name(hton));
1371
1231
for (int i=0; i < got; i ++)
1373
1233
my_xid x=info->list[i].get_my_xid();
1374
1234
if (!x) // not "mine" - that is generated by external TM
1377
char buf[XIDDATASIZE*4+6]; // see xid_to_str
1378
sql_print_information("ignore xid %s", xid_to_str(buf, info->list+i));
1380
1236
xid_cache_insert(info->list+i, XA_PREPARED);
1381
1237
info->found_foreign_xids++;
1389
1245
// recovery mode
1390
1246
if (info->commit_list ?
1391
hash_search(info->commit_list, (uchar *)&x, sizeof(x)) != 0 :
1247
hash_search(info->commit_list, (unsigned char *)&x, sizeof(x)) != 0 :
1392
1248
tc_heuristic_recover == TC_HEURISTIC_RECOVER_COMMIT)
1395
char buf[XIDDATASIZE*4+6]; // see xid_to_str
1396
sql_print_information("commit xid %s", xid_to_str(buf, info->list+i));
1398
1250
hton->commit_by_xid(hton, info->list+i);
1403
char buf[XIDDATASIZE*4+6]; // see xid_to_str
1404
sql_print_information("rollback xid %s",
1405
xid_to_str(buf, info->list+i));
1407
1254
hton->rollback_by_xid(hton, info->list+i);
1417
1264
int ha_recover(HASH *commit_list)
1419
1266
struct xarecover_st info;
1420
DBUG_ENTER("ha_recover");
1421
1267
info.found_foreign_xids= info.found_my_xids= 0;
1422
1268
info.commit_list= commit_list;
1423
1269
info.dry_run= (info.commit_list==0 && tc_heuristic_recover==0);
1424
1270
info.list= NULL;
1426
1272
/* commit_list and tc_heuristic_recover cannot be set both */
1427
DBUG_ASSERT(info.commit_list==0 || tc_heuristic_recover==0);
1273
assert(info.commit_list==0 || tc_heuristic_recover==0);
1428
1274
/* if either is set, total_ha_2pc must be set too */
1429
DBUG_ASSERT(info.dry_run || total_ha_2pc>(ulong)opt_bin_log);
1275
assert(info.dry_run || total_ha_2pc>(uint32_t)opt_bin_log);
1431
if (total_ha_2pc <= (ulong)opt_bin_log)
1277
if (total_ha_2pc <= (uint32_t)opt_bin_log)
1434
1280
if (info.commit_list)
1435
sql_print_information("Starting crash recovery...");
1281
sql_print_information(_("Starting crash recovery..."));
1438
1284
#ifndef WILL_BE_DELETED_LATER
1442
1288
rollback all pending transactions, without risking inconsistent data
1445
DBUG_ASSERT(total_ha_2pc == (ulong) opt_bin_log+1); // only InnoDB and binlog
1291
assert(total_ha_2pc == (uint32_t) opt_bin_log+1); // only InnoDB and binlog
1446
1292
tc_heuristic_recover= TC_HEURISTIC_RECOVER_ROLLBACK; // forcing ROLLBACK
1456
1302
if (!info.list)
1458
1304
sql_print_error(ER(ER_OUTOFMEMORY), info.len*sizeof(XID));
1462
1308
plugin_foreach(NULL, xarecover_handlerton,
1463
MYSQL_STORAGE_ENGINE_PLUGIN, &info);
1309
DRIZZLE_STORAGE_ENGINE_PLUGIN, &info);
1465
my_free((uchar*)info.list, MYF(0));
1311
free((unsigned char*)info.list);
1466
1312
if (info.found_foreign_xids)
1467
sql_print_warning("Found %d prepared XA transactions",
1313
sql_print_warning(_("Found %d prepared XA transactions"),
1468
1314
info.found_foreign_xids);
1469
1315
if (info.dry_run && info.found_my_xids)
1471
sql_print_error("Found %d prepared transactions! It means that mysqld was "
1472
"not shut down properly last time and critical recovery "
1473
"information (last binlog or %s file) was manually deleted "
1474
"after a crash. You have to start mysqld with "
1475
"--tc-heuristic-recover switch to commit or rollback "
1476
"pending transactions.",
1317
sql_print_error(_("Found %d prepared transactions! It means that drizzled "
1318
"was not shut down properly last time and critical "
1319
"recovery information (last binlog or %s file) was "
1320
"manually deleted after a crash. You have to start "
1321
"drizzled with the --tc-heuristic-recover switch to "
1322
"commit or rollback pending transactions."),
1477
1323
info.found_my_xids, opt_tc_log_file);
1480
1326
if (info.commit_list)
1481
sql_print_information("Crash recovery finished.");
1327
sql_print_information(_("Crash recovery finished."));
1496
1342
Protocol *protocol= thd->protocol;
1499
DBUG_ENTER("mysql_xa_recover");
1501
1346
field_list.push_back(new Item_int("formatID", 0, MY_INT32_NUM_DECIMAL_DIGITS));
1502
1347
field_list.push_back(new Item_int("gtrid_length", 0, MY_INT32_NUM_DECIMAL_DIGITS));
1506
1351
if (protocol->send_fields(&field_list,
1507
1352
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
1510
1355
pthread_mutex_lock(&LOCK_xid_cache);
1511
1356
while ((xs= (XID_STATE*)hash_element(&xid_cache, i++)))
1513
1358
if (xs->xa_state==XA_PREPARED)
1515
1360
protocol->prepare_for_resend();
1516
protocol->store_longlong((longlong)xs->xid.formatID, FALSE);
1517
protocol->store_longlong((longlong)xs->xid.gtrid_length, FALSE);
1518
protocol->store_longlong((longlong)xs->xid.bqual_length, FALSE);
1361
protocol->store_int64_t((int64_t)xs->xid.formatID, false);
1362
protocol->store_int64_t((int64_t)xs->xid.gtrid_length, false);
1363
protocol->store_int64_t((int64_t)xs->xid.bqual_length, false);
1519
1364
protocol->store(xs->xid.data, xs->xid.gtrid_length+xs->xid.bqual_length,
1520
1365
&my_charset_bin);
1521
1366
if (protocol->write())
1523
1368
pthread_mutex_unlock(&LOCK_xid_cache);
1529
1374
pthread_mutex_unlock(&LOCK_xid_cache);
1552
static my_bool release_temporary_latches(THD *thd, plugin_ref plugin,
1397
static bool release_temporary_latches(THD *thd, plugin_ref plugin,
1398
void *unused __attribute__((unused)))
1555
1400
handlerton *hton= plugin_data(plugin, handlerton *);
1557
1402
if (hton->state == SHOW_OPTION_YES && hton->release_temporary_latches)
1558
1403
hton->release_temporary_latches(hton, thd);
1564
1409
int ha_release_temporary_latches(THD *thd)
1566
plugin_foreach(thd, release_temporary_latches, MYSQL_STORAGE_ENGINE_PLUGIN,
1411
plugin_foreach(thd, release_temporary_latches, DRIZZLE_STORAGE_ENGINE_PLUGIN,
1572
1417
int ha_rollback_to_savepoint(THD *thd, SAVEPOINT *sv)
1575
THD_TRANS *trans= (thd->in_sub_stmt ? &thd->transaction.stmt :
1576
&thd->transaction.all);
1420
THD_TRANS *trans= &thd->transaction.all;
1577
1421
Ha_trx_info *ha_info, *ha_info_next;
1579
DBUG_ENTER("ha_rollback_to_savepoint");
1581
1423
trans->no_2pc=0;
1583
1425
rolling back to savepoint in all storage engines that were part of the
1589
1431
handlerton *ht= ha_info->ht();
1591
DBUG_ASSERT(ht->savepoint_set != 0);
1433
assert(ht->savepoint_set != 0);
1592
1434
if ((err= ht->savepoint_rollback(ht, thd,
1593
(uchar *)(sv+1)+ht->savepoint_offset)))
1435
(unsigned char *)(sv+1)+ht->savepoint_offset)))
1594
1436
{ // cannot happen
1595
1437
my_error(ER_ERROR_DURING_ROLLBACK, MYF(0), err);
1609
1451
handlerton *ht= ha_info->ht();
1610
if ((err= ht->rollback(ht, thd, !thd->in_sub_stmt)))
1452
if ((err= ht->rollback(ht, thd, !(0))))
1611
1453
{ // cannot happen
1612
1454
my_error(ER_ERROR_DURING_ROLLBACK, MYF(0), err);
1629
1471
int ha_savepoint(THD *thd, SAVEPOINT *sv)
1632
THD_TRANS *trans= (thd->in_sub_stmt ? &thd->transaction.stmt :
1633
&thd->transaction.all);
1474
THD_TRANS *trans= &thd->transaction.all;
1634
1475
Ha_trx_info *ha_info= trans->ha_list;
1635
DBUG_ENTER("ha_savepoint");
1636
1476
for (; ha_info; ha_info= ha_info->next())
1639
1479
handlerton *ht= ha_info->ht();
1641
1481
if (! ht->savepoint_set)
1643
1483
my_error(ER_CHECK_NOT_IMPLEMENTED, MYF(0), "SAVEPOINT");
1647
if ((err= ht->savepoint_set(ht, thd, (uchar *)(sv+1)+ht->savepoint_offset)))
1487
if ((err= ht->savepoint_set(ht, thd, (unsigned char *)(sv+1)+ht->savepoint_offset)))
1648
1488
{ // cannot happen
1649
1489
my_error(ER_GET_ERRNO, MYF(0), err);
1656
1496
engines are prepended to the beginning of the list.
1658
1498
sv->ha_list= trans->ha_list;
1662
1502
int ha_release_savepoint(THD *thd, SAVEPOINT *sv)
1665
1505
Ha_trx_info *ha_info= sv->ha_list;
1666
DBUG_ENTER("ha_release_savepoint");
1668
1507
for (; ha_info; ha_info= ha_info->next())
1671
1510
handlerton *ht= ha_info->ht();
1672
1511
/* Savepoint life time is enclosed into transaction life time. */
1674
1513
if (!ht->savepoint_release)
1676
1515
if ((err= ht->savepoint_release(ht, thd,
1677
(uchar *)(sv+1) + ht->savepoint_offset)))
1516
(unsigned char *)(sv+1) + ht->savepoint_offset)))
1678
1517
{ // cannot happen
1679
1518
my_error(ER_GET_ERRNO, MYF(0), err);
1687
static my_bool snapshot_handlerton(THD *thd, plugin_ref plugin,
1526
static bool snapshot_handlerton(THD *thd, plugin_ref plugin, void *arg)
1690
1528
handlerton *hton= plugin_data(plugin, handlerton *);
1691
1529
if (hton->state == SHOW_OPTION_YES &&
1694
1532
hton->start_consistent_snapshot(hton, thd);
1695
1533
*((bool *)arg)= false;
1700
1538
int ha_start_consistent_snapshot(THD *thd)
1702
1540
bool warn= true;
1704
plugin_foreach(thd, snapshot_handlerton, MYSQL_STORAGE_ENGINE_PLUGIN, &warn);
1542
plugin_foreach(thd, snapshot_handlerton, DRIZZLE_STORAGE_ENGINE_PLUGIN, &warn);
1707
1545
Same idea as when one wants to CREATE TABLE in one engine which does not
1711
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
1549
push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
1712
1550
"This MySQL server does not support any "
1713
1551
"consistent-read capable storage engine");
1718
static my_bool flush_handlerton(THD *thd, plugin_ref plugin,
1556
static bool flush_handlerton(THD *thd __attribute__((unused)),
1558
void *arg __attribute__((unused)))
1721
1560
handlerton *hton= plugin_data(plugin, handlerton *);
1722
1561
if (hton->state == SHOW_OPTION_YES && hton->flush_logs &&
1723
1562
hton->flush_logs(hton))
1731
1570
if (db_type == NULL)
1733
1572
if (plugin_foreach(NULL, flush_handlerton,
1734
MYSQL_STORAGE_ENGINE_PLUGIN, 0))
1573
DRIZZLE_STORAGE_ENGINE_PLUGIN, 0))
1739
1578
if (db_type->state != SHOW_OPTION_YES ||
1740
1579
(db_type->flush_logs && db_type->flush_logs(db_type)))
1746
1585
static const char *check_lowercase_names(handler *file, const char *path,
1771
1610
struct Ha_delete_table_error_handler: public Internal_error_handler
1774
virtual bool handle_error(uint sql_errno,
1613
virtual bool handle_error(uint32_t sql_errno,
1775
1614
const char *message,
1776
MYSQL_ERROR::enum_warning_level level,
1615
DRIZZLE_ERROR::enum_warning_level level,
1778
char buff[MYSQL_ERRMSG_SIZE];
1617
char buff[DRIZZLE_ERRMSG_SIZE];
1783
1622
Ha_delete_table_error_handler::
1784
handle_error(uint sql_errno,
1623
handle_error(uint32_t sql_errno __attribute__((unused)),
1785
1624
const char *message,
1786
MYSQL_ERROR::enum_warning_level level,
1625
DRIZZLE_ERROR::enum_warning_level level __attribute__((unused)),
1626
THD *thd __attribute__((unused)))
1789
1628
/* Grab the error message */
1790
1629
strmake(buff, message, sizeof(buff)-1);
1803
1642
char tmp_path[FN_REFLEN];
1806
1645
TABLE_SHARE dummy_share;
1807
DBUG_ENTER("ha_delete_table");
1809
bzero((char*) &dummy_table, sizeof(dummy_table));
1810
bzero((char*) &dummy_share, sizeof(dummy_share));
1647
memset(&dummy_table, 0, sizeof(dummy_table));
1648
memset(&dummy_share, 0, sizeof(dummy_share));
1811
1649
dummy_table.s= &dummy_share;
1813
/* DB_TYPE_UNKNOWN is used in ALTER TABLE when renaming only .frm files */
1651
/* DB_TYPE_UNKNOWN is used in ALTER Table when renaming only .frm files */
1814
1652
if (table_type == NULL ||
1815
1653
! (file=get_new_handler((TABLE_SHARE*)0, thd->mem_root, table_type)))
1816
DBUG_RETURN(ENOENT);
1818
1656
path= check_lowercase_names(file, path, tmp_path);
1819
1657
if ((error= file->ha_delete_table(path)) && generate_warning)
1846
1684
XXX: should we convert *all* errors to warnings here?
1847
1685
What if the error is fatal?
1849
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, error,
1687
push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_ERROR, error,
1850
1688
ha_delete_table_error_handler.buff);
1856
1694
/****************************************************************************
1864
1702
on this->table->mem_root and we will not be able to reclaim that memory
1865
1703
when the clone handler object is destroyed.
1867
if (!(new_handler->ref= (uchar*) alloc_root(mem_root, ALIGN_SIZE(ref_length)*2)))
1705
if (!(new_handler->ref= (unsigned char*) alloc_root(mem_root, ALIGN_SIZE(ref_length)*2)))
1869
1707
if (new_handler && !new_handler->ha_open(table,
1870
1708
table->s->normalized_path.str,
1872
1710
HA_OPEN_IGNORE_IF_LOCKED))
1873
1711
return new_handler;
1889
1727
THD *handler::ha_thd(void) const
1891
DBUG_ASSERT(!table || !table->in_use || table->in_use == current_thd);
1729
assert(!table || !table->in_use || table->in_use == current_thd);
1892
1730
return (table && table->in_use) ? table->in_use : current_thd;
1897
Get tablespace name from handler
1898
Returns the tablespace name associated
1899
with the table or NULL if not defined
1902
char* handler::get_tablespace_name()
1904
return table->s->tablespace;
1908
1734
Open database-handler.
1910
1736
Try O_RDONLY if cannot open as O_RDWR
1911
1737
Don't wait for locks if not HA_OPEN_WAIT_IF_LOCKED is set
1913
int handler::ha_open(TABLE *table_arg, const char *name, int mode,
1739
int handler::ha_open(Table *table_arg, const char *name, int mode,
1914
1740
int test_if_locked)
1917
DBUG_ENTER("handler::ha_open");
1919
("name: %s db_type: %d db_stat: %d mode: %d lock_test: %d",
1920
name, ht->db_type, table_arg->db_stat, mode,
1923
1744
table= table_arg;
1924
DBUG_ASSERT(table->s == table_share);
1925
DBUG_ASSERT(alloc_root_inited(&table->mem_root));
1745
assert(table->s == table_share);
1746
assert(alloc_root_inited(&table->mem_root));
1927
1748
if ((error=open(name,mode,test_if_locked)))
1945
1765
(void) extra(HA_EXTRA_NO_READCHECK); // Not needed in SQL
1947
1767
/* ref is already allocated for us if we're called from handler::clone() */
1948
if (!ref && !(ref= (uchar*) alloc_root(&table->mem_root,
1768
if (!ref && !(ref= (unsigned char*) alloc_root(&table->mem_root,
1949
1769
ALIGN_SIZE(ref_length)*2)))
1965
1785
handlers for random position
1968
int handler::rnd_pos_by_record(uchar *record)
1788
int handler::rnd_pos_by_record(unsigned char *record)
1970
1790
register int error;
1971
DBUG_ENTER("handler::rnd_pos_by_record");
1973
1792
position(record);
1974
1793
if (inited && (error= ha_index_end()))
1976
if ((error= ha_rnd_init(FALSE)))
1795
if ((error= ha_rnd_init(false)))
1979
DBUG_RETURN(rnd_pos(record, ref));
1798
return(rnd_pos(record, ref));
1985
1804
This is never called for InnoDB tables, as these table types
1986
1805
has the HA_STATS_RECORDS_IS_EXACT set.
1988
int handler::read_first_row(uchar * buf, uint primary_key)
1807
int handler::read_first_row(unsigned char * buf, uint32_t primary_key)
1990
1809
register int error;
1991
DBUG_ENTER("handler::read_first_row");
1993
1811
ha_statistic_increment(&SSV::ha_read_first_count);
2075
1893
the offset is larger than the column's max possible value, i.e. not even
2076
1894
the first sequence value may be inserted. User will receive warning.
2078
DBUG_PRINT("info",("auto_increment: nr: %lu cannot honour "
2079
"auto_increment_offset: %lu",
2080
(ulong) nr, variables->auto_increment_offset));
2083
1898
if (variables->auto_increment_increment == 1)
2166
1981
int handler::update_auto_increment()
2168
1983
uint64_t nr, nb_reserved_values;
2170
1985
THD *thd= table->in_use;
2171
1986
struct system_variables *variables= &thd->variables;
2172
DBUG_ENTER("handler::update_auto_increment");
2175
1989
next_insert_id is a "cursor" into the reserved interval, it may go greater
2176
1990
than the interval, but not smaller.
2178
DBUG_ASSERT(next_insert_id >= auto_inc_interval_for_cur_row.minimum());
1992
assert(next_insert_id >= auto_inc_interval_for_cur_row.minimum());
2180
if (((nr= table->next_number_field->val_int()) != 0) ||
2181
(table->auto_increment_field_not_null && (thd->variables.sql_mode & MODE_NO_AUTO_VALUE_ON_ZERO)))
1994
if ((nr= table->next_number_field->val_int()) != 0)
2184
1997
Update next_insert_id if we had already generated a value in this
2207
2020
handler::estimation_rows_to_insert was set by
2208
2021
handler::ha_start_bulk_insert(); if 0 it means "unknown".
2210
uint nb_already_reserved_intervals=
2023
uint32_t nb_already_reserved_intervals=
2211
2024
thd->auto_inc_intervals_in_cur_stmt_for_binlog.nb_elements();
2212
2025
uint64_t nb_desired_values;
2258
2071
if (table->s->next_number_keypart == 0)
2260
2073
/* We must defer the appending until "nr" has been possibly truncated */
2266
For such auto_increment there is no notion of interval, just a
2267
singleton. The interval is not even stored in
2268
thd->auto_inc_interval_for_cur_row, so we are sure to call the engine
2271
DBUG_PRINT("info",("auto_increment: special not-first-in-index"));
2275
DBUG_PRINT("info",("auto_increment: %lu", (ulong) nr));
2277
if (unlikely(table->next_number_field->store((longlong) nr, TRUE)))
2078
if (unlikely(table->next_number_field->store((int64_t) nr, true)))
2280
2081
first test if the query was aborted due to strict mode constraints
2282
2083
if (thd->killed == THD::KILL_BAD_DATA)
2283
DBUG_RETURN(HA_ERR_AUTOINC_ERANGE);
2084
return(HA_ERR_AUTOINC_ERANGE);
2286
2087
field refused this value (overflow) and truncated it, use the result of
2291
2092
interval will cause a duplicate key).
2293
2094
nr= prev_insert_id(table->next_number_field->val_int(), variables);
2294
if (unlikely(table->next_number_field->store((longlong) nr, TRUE)))
2095
if (unlikely(table->next_number_field->store((int64_t) nr, true)))
2295
2096
nr= table->next_number_field->val_int();
2338
2139
void handler::column_bitmaps_signal()
2340
DBUG_ENTER("column_bitmaps_signal");
2341
DBUG_PRINT("info", ("read_set: 0x%lx write_set: 0x%lx", (long) table->read_set,
2342
(long) table->write_set));
2350
2148
offset and increment means that we want values to be of the form
2351
2149
offset + N * increment, where N>=0 is integer.
2352
2150
If the function sets *first_value to ~(uint64_t)0 it means an error.
2353
If the function sets *nb_reserved_values to ULONGLONG_MAX it means it has
2151
If the function sets *nb_reserved_values to UINT64_MAX it means it has
2354
2152
reserved to "positive infinite".
2359
2157
@param first_value (OUT) the first value reserved by the handler
2360
2158
@param nb_reserved_values (OUT) how many values the handler reserved
2362
void handler::get_auto_increment(uint64_t offset, uint64_t increment,
2363
uint64_t nb_desired_values,
2160
void handler::get_auto_increment(uint64_t offset __attribute__((unused)),
2161
uint64_t increment __attribute__((unused)),
2162
uint64_t nb_desired_values __attribute__((unused)),
2364
2163
uint64_t *first_value,
2365
2164
uint64_t *nb_reserved_values)
2380
2179
use nr+increment without checking again with the handler, in
2381
2180
handler::update_auto_increment()), so reserves to infinite.
2383
*nb_reserved_values= ULONGLONG_MAX;
2182
*nb_reserved_values= UINT64_MAX;
2387
uchar key[MAX_KEY_LENGTH];
2186
unsigned char key[MAX_KEY_LENGTH];
2388
2187
key_copy(key, table->record[0],
2389
2188
table->key_info + table->s->next_number_index,
2390
2189
table->s->next_number_key_offset);
2431
void handler::print_keydup_error(uint key_nr, const char *msg)
2230
void handler::print_keydup_error(uint32_t key_nr, const char *msg)
2433
2232
/* Write the duplicated key in the error message */
2434
2233
char key[MAX_KEY_LENGTH];
2445
2244
/* Table is opened and defined at this point */
2446
2245
key_unpack(&str,table,(uint) key_nr);
2447
uint max_length=MYSQL_ERRMSG_SIZE-(uint) strlen(msg);
2246
uint32_t max_length=DRIZZLE_ERRMSG_SIZE-(uint) strlen(msg);
2448
2247
if (str.length() >= max_length)
2450
2249
str.length(max_length-4);
2468
2267
void handler::print_error(int error, myf errflag)
2470
DBUG_ENTER("handler::print_error");
2471
DBUG_PRINT("enter",("error: %d",error));
2473
2269
int textno=ER_GET_ERRNO;
2474
2270
switch (error) {
2492
2288
case HA_ERR_FOUND_DUPP_KEY:
2494
uint key_nr=get_dup_key(error);
2290
uint32_t key_nr=get_dup_key(error);
2495
2291
if ((int) key_nr >= 0)
2497
2293
print_keydup_error(key_nr, ER(ER_DUP_ENTRY_WITH_KEY_NAME));
2500
2296
textno=ER_DUP_KEY;
2503
2299
case HA_ERR_FOREIGN_DUPLICATE_KEY:
2505
uint key_nr= get_dup_key(error);
2301
uint32_t key_nr= get_dup_key(error);
2506
2302
if ((int) key_nr >= 0)
2304
uint32_t max_length;
2509
2305
/* Write the key in the error message */
2510
2306
char key[MAX_KEY_LENGTH];
2511
2307
String str(key,sizeof(key),system_charset_info);
2512
2308
/* Table is opened and defined at this point */
2513
2309
key_unpack(&str,table,(uint) key_nr);
2514
max_length= (MYSQL_ERRMSG_SIZE-
2310
max_length= (DRIZZLE_ERRMSG_SIZE-
2515
2311
(uint) strlen(ER(ER_FOREIGN_DUPLICATE_KEY)));
2516
2312
if (str.length() >= max_length)
2583
2379
get_error_message(error, &str);
2584
2380
my_error(ER_ROW_IS_REFERENCED_2, MYF(0), str.c_ptr_safe());
2587
2383
case HA_ERR_NO_REFERENCED_ROW:
2590
2386
get_error_message(error, &str);
2591
2387
my_error(ER_NO_REFERENCED_ROW_2, MYF(0), str.c_ptr_safe());
2594
2390
case HA_ERR_TABLE_DEF_CHANGED:
2595
2391
textno=ER_TABLE_DEF_CHANGED;
2597
2393
case HA_ERR_NO_SUCH_TABLE:
2598
2394
my_error(ER_NO_SUCH_TABLE, MYF(0), table_share->db.str,
2599
2395
table_share->table_name.str);
2601
2397
case HA_ERR_RBR_LOGGING_FAILED:
2602
2398
textno= ER_BINLOG_ROW_LOGGING_FAILED;
2604
2400
case HA_ERR_DROP_INDEX_FK:
2606
2402
const char *ptr= "???";
2607
uint key_nr= get_dup_key(error);
2403
uint32_t key_nr= get_dup_key(error);
2608
2404
if ((int) key_nr >= 0)
2609
2405
ptr= table->key_info[key_nr].name;
2610
2406
my_error(ER_DROP_INDEX_FK, MYF(0), ptr);
2613
2409
case HA_ERR_TABLE_NEEDS_UPGRADE:
2614
2410
textno=ER_TABLE_NEEDS_UPGRADE;
2625
2421
case HA_ERR_LOCK_OR_ACTIVE_TRANSACTION:
2626
2422
my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
2627
2423
ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
2632
2428
/* The error was "unknown" to this function.
2633
2429
Ask handler if it has got a message for this error */
2634
bool temporary= FALSE;
2430
bool temporary= false;
2636
2432
temporary= get_error_message(error, &str);
2637
2433
if (!str.is_empty())
2662
2458
Returns true if this is a temporary error
2664
bool handler::get_error_message(int error, String* buf)
2460
bool handler::get_error_message(int error __attribute__((unused)),
2461
String* buf __attribute__((unused)))
2686
2483
if (!keypart->fieldnr)
2688
2485
Field *field= table->field[keypart->fieldnr-1];
2689
if (field->type() == MYSQL_TYPE_BLOB)
2486
if (field->type() == DRIZZLE_TYPE_BLOB)
2691
2488
if (check_opt->sql_flags & TT_FOR_UPGRADE)
2692
2489
check_opt->flags= T_MEDIUM;
2719
2515
update frm version for temporary tables as this code doesn't support
2720
2516
temporary tables.
2722
if (table->s->mysql_version == MYSQL_VERSION_ID)
2725
strxmov(path, table->s->normalized_path.str, reg_ext, NullS);
2727
if ((file= my_open(path, O_RDWR|O_BINARY, MYF(MY_WME))) >= 0)
2518
if (table->s->mysql_version == DRIZZLE_VERSION_ID)
2521
strxmov(path, table->s->normalized_path.str, reg_ext, NULL);
2523
if ((file= my_open(path, O_RDWR, MYF(MY_WME))) >= 0)
2525
unsigned char version[4];
2730
2526
char *key= table->s->table_cache_key.str;
2731
uint key_length= table->s->table_cache_key.length;
2527
uint32_t key_length= table->s->table_cache_key.length;
2733
2529
HASH_SEARCH_STATE state;
2735
int4store(version, MYSQL_VERSION_ID);
2531
int4store(version, DRIZZLE_VERSION_ID);
2737
if (pwrite(file, (uchar*)version, 4, 51L) == 0)
2533
if (pwrite(file, (unsigned char*)version, 4, 51L) == 0)
2743
for (entry=(TABLE*) hash_first(&open_cache,(uchar*) key,key_length, &state);
2539
for (entry=(Table*) hash_first(&open_cache,(unsigned char*) key,key_length, &state);
2745
entry= (TABLE*) hash_next(&open_cache,(uchar*) key,key_length, &state))
2746
entry->s->mysql_version= MYSQL_VERSION_ID;
2541
entry= (Table*) hash_next(&open_cache,(unsigned char*) key,key_length, &state))
2542
entry->s->mysql_version= DRIZZLE_VERSION_ID;
2750
VOID(my_close(file,MYF(MY_WME)));
2751
DBUG_RETURN(result);
2546
my_close(file,MYF(MY_WME));
2758
2554
key if error because of duplicated keys
2760
uint handler::get_dup_key(int error)
2556
uint32_t handler::get_dup_key(int error)
2762
DBUG_ENTER("handler::get_dup_key");
2763
2558
table->file->errkey = (uint) -1;
2764
2559
if (error == HA_ERR_FOUND_DUPP_KEY || error == HA_ERR_FOREIGN_DUPLICATE_KEY ||
2765
2560
error == HA_ERR_FOUND_DUPP_UNIQUE ||
2766
2561
error == HA_ERR_DROP_INDEX_FK)
2767
2562
info(HA_STATUS_ERRKEY | HA_STATUS_NO_LOCK);
2768
DBUG_RETURN(table->file->errkey);
2563
return(table->file->errkey);
2851
if ((table->s->mysql_version >= MYSQL_VERSION_ID) &&
2646
if ((table->s->mysql_version >= DRIZZLE_VERSION_ID) &&
2852
2647
(check_opt->sql_flags & TT_FOR_UPGRADE))
2855
if (table->s->mysql_version < MYSQL_VERSION_ID)
2650
if (table->s->mysql_version < DRIZZLE_VERSION_ID)
2857
2652
if ((error= check_old_types()))
2888
2683
if (ha_info->is_started())
2890
DBUG_ASSERT(has_transactions());
2685
assert(has_transactions());
2892
2687
table_share can be NULL in ha_delete_table(). See implementation
2893
2688
of standalone function ha_delete_table() in sql_base.cc.
3149
2944
Tell the storage engine that it is allowed to "disable transaction" in the
3150
2945
handler. It is a hint that ACID is not required - it is used in NDB for
3151
ALTER TABLE, for example, when data are copied to temporary table.
2946
ALTER Table, for example, when data are copied to temporary table.
3152
2947
A storage engine may treat this hint any way it likes. NDB for example
3153
2948
starts to commit every now and then automatically.
3154
2949
This hint can be safely ignored.
3156
2951
int ha_enable_transaction(THD *thd, bool on)
3159
DBUG_ENTER("ha_enable_transaction");
3160
DBUG_PRINT("enter", ("on: %d", (int) on));
3162
2955
if ((thd->transaction.on= on))
3170
2963
if (!(error= ha_commit_trans(thd, 0)))
3171
2964
error= end_trans(thd, COMMIT);
3176
int handler::index_next_same(uchar *buf, const uchar *key, uint keylen)
2969
int handler::index_next_same(unsigned char *buf, const unsigned char *key, uint32_t keylen)
3179
DBUG_ENTER("index_next_same");
3180
2972
if (!(error=index_next(buf)))
3182
2974
my_ptrdiff_t ptrdiff= buf - table->record[0];
3183
uchar *save_record_0= NULL;
2975
unsigned char *save_record_0= NULL;
3184
2976
KEY *key_info= NULL;
3185
2977
KEY_PART_INFO *key_part;
3186
2978
KEY_PART_INFO *key_part_end= NULL;
3243
3035
bool update_create_info)
3247
3039
char name_buff[FN_REFLEN];
3248
3040
const char *name;
3249
3041
TABLE_SHARE share;
3250
DBUG_ENTER("ha_create_table");
3252
3043
init_tmp_table_share(thd, &share, db, 0, table_name, path);
3253
3044
if (open_table_def(thd, &share, 0) ||
3258
3049
if (update_create_info)
3259
update_create_info_from_table(create_info, &table);
3050
table.updateCreateInfo(create_info);
3261
3052
name= check_lowercase_names(table.file, share.path.str, name_buff);
3263
3054
error= table.file->ha_create(name, &table, create_info);
3264
VOID(closefrm(&table, 0));
3055
closefrm(&table, 0);
3267
strxmov(name_buff, db, ".", table_name, NullS);
3058
strxmov(name_buff, db, ".", table_name, NULL);
3268
3059
my_error(ER_CANT_CREATE_TABLE, MYF(ME_BELL+ME_WAITTANG), name_buff, error);
3271
3062
free_table_share(&share);
3272
DBUG_RETURN(error != 0);
3288
3079
int ha_create_table_from_engine(THD* thd, const char *db, const char *name)
3082
unsigned char *frmblob;
3293
3084
char path[FN_REFLEN];
3294
3085
HA_CREATE_INFO create_info;
3296
3087
TABLE_SHARE share;
3297
DBUG_ENTER("ha_create_table_from_engine");
3298
DBUG_PRINT("enter", ("name '%s'.'%s'", db, name));
3300
bzero((uchar*) &create_info,sizeof(create_info));
3089
memset(&create_info, 0, sizeof(create_info));
3301
3090
if ((error= ha_discover(thd, db, name, &frmblob, &frmlen)))
3303
3092
/* Table could not be discovered and thus not created */
3312
3101
build_table_filename(path, FN_REFLEN-1, db, name, "", 0);
3313
3102
// Save the frm file
3314
3103
error= writefrm(path, frmblob, frmlen);
3315
my_free(frmblob, MYF(0));
3319
3108
init_tmp_table_share(thd, &share, db, 0, name, path);
3320
3109
if (open_table_def(thd, &share, 0))
3324
3113
if (open_table_from_share(thd, &share, "" ,0, 0, 0, &table, OTM_OPEN))
3326
3115
free_table_share(&share);
3330
update_create_info_from_table(&create_info, &table);
3119
table.updateCreateInfo(&create_info);
3331
3120
create_info.table_options|= HA_OPTION_CREATE_FROM_ENGINE;
3333
3122
check_lowercase_names(table.file, path, path);
3334
3123
error=table.file->ha_create(path, &table, &create_info);
3335
VOID(closefrm(&table, 1));
3124
closefrm(&table, 1);
3337
DBUG_RETURN(error != 0);
3340
3129
void st_ha_check_opt::init()
3358
3147
Init a key cache if it has not been initied before.
3360
int ha_init_key_cache(const char *name, KEY_CACHE *key_cache)
3149
int ha_init_key_cache(const char *name __attribute__((unused)),
3150
KEY_CACHE *key_cache)
3362
DBUG_ENTER("ha_init_key_cache");
3364
3152
if (!key_cache->key_cache_inited)
3366
3154
pthread_mutex_lock(&LOCK_global_system_variables);
3367
ulong tmp_buff_size= (ulong) key_cache->param_buff_size;
3368
uint tmp_block_size= (uint) key_cache->param_block_size;
3369
uint division_limit= key_cache->param_division_limit;
3370
uint age_threshold= key_cache->param_age_threshold;
3155
uint32_t tmp_buff_size= (uint32_t) key_cache->param_buff_size;
3156
uint32_t tmp_block_size= (uint) key_cache->param_block_size;
3157
uint32_t division_limit= key_cache->param_division_limit;
3158
uint32_t age_threshold= key_cache->param_age_threshold;
3371
3159
pthread_mutex_unlock(&LOCK_global_system_variables);
3372
DBUG_RETURN(!init_key_cache(key_cache,
3160
return(!init_key_cache(key_cache,
3373
3161
tmp_block_size,
3375
3163
division_limit, age_threshold));
3384
3172
int ha_resize_key_cache(KEY_CACHE *key_cache)
3386
DBUG_ENTER("ha_resize_key_cache");
3388
3174
if (key_cache->key_cache_inited)
3390
3176
pthread_mutex_lock(&LOCK_global_system_variables);
3391
3177
long tmp_buff_size= (long) key_cache->param_buff_size;
3392
3178
long tmp_block_size= (long) key_cache->param_block_size;
3393
uint division_limit= key_cache->param_division_limit;
3394
uint age_threshold= key_cache->param_age_threshold;
3179
uint32_t division_limit= key_cache->param_division_limit;
3180
uint32_t age_threshold= key_cache->param_age_threshold;
3395
3181
pthread_mutex_unlock(&LOCK_global_system_variables);
3396
DBUG_RETURN(!resize_key_cache(key_cache, tmp_block_size,
3182
return(!resize_key_cache(key_cache, tmp_block_size,
3398
3184
division_limit, age_threshold));
3409
3195
if (key_cache->key_cache_inited)
3411
3197
pthread_mutex_lock(&LOCK_global_system_variables);
3412
uint division_limit= key_cache->param_division_limit;
3413
uint age_threshold= key_cache->param_age_threshold;
3198
uint32_t division_limit= key_cache->param_division_limit;
3199
uint32_t age_threshold= key_cache->param_age_threshold;
3414
3200
pthread_mutex_unlock(&LOCK_global_system_variables);
3415
3201
change_key_cache_param(key_cache, division_limit, age_threshold);
3452
3238
const char *db;
3453
3239
const char *name;
3240
unsigned char **frmblob;
3455
3241
size_t *frmlen;
3458
static my_bool discover_handlerton(THD *thd, plugin_ref plugin,
3244
static bool discover_handlerton(THD *thd, plugin_ref plugin,
3461
3247
st_discover_args *vargs= (st_discover_args *)arg;
3462
3248
handlerton *hton= plugin_data(plugin, handlerton *);
3464
3250
(!(hton->discover(hton, thd, vargs->db, vargs->name,
3465
3251
vargs->frmblob,
3466
3252
vargs->frmlen))))
3472
3258
int ha_discover(THD *thd, const char *db, const char *name,
3473
uchar **frmblob, size_t *frmlen)
3259
unsigned char **frmblob, size_t *frmlen)
3475
3261
int error= -1; // Table does not exist in any handler
3476
DBUG_ENTER("ha_discover");
3477
DBUG_PRINT("enter", ("db: %s, name: %s", db, name));
3478
3262
st_discover_args args= {db, name, frmblob, frmlen};
3480
3264
if (is_prefix(name,tmp_file_prefix)) /* skip temporary tables */
3483
3267
if (plugin_foreach(thd, discover_handlerton,
3484
MYSQL_STORAGE_ENGINE_PLUGIN, &args))
3268
DRIZZLE_STORAGE_ENGINE_PLUGIN, &args))
3488
3272
status_var_increment(thd->status_var.ha_discover_count);
3523
static my_bool table_exists_in_engine_handlerton(THD *thd, plugin_ref plugin,
3307
static bool table_exists_in_engine_handlerton(THD *thd, plugin_ref plugin,
3526
3310
st_table_exists_in_engine_args *vargs= (st_table_exists_in_engine_args *)arg;
3527
3311
handlerton *hton= plugin_data(plugin, handlerton *);
3534
3318
vargs->err = err;
3535
3319
if (vargs->err == HA_ERR_TABLE_EXIST)
3541
3325
int ha_table_exists_in_engine(THD* thd, const char* db, const char* name)
3543
DBUG_ENTER("ha_table_exists_in_engine");
3544
DBUG_PRINT("enter", ("db: %s, name: %s", db, name));
3545
3327
st_table_exists_in_engine_args args= {db, name, HA_ERR_NO_SUCH_TABLE};
3546
3328
plugin_foreach(thd, table_exists_in_engine_handlerton,
3547
MYSQL_STORAGE_ENGINE_PLUGIN, &args);
3548
DBUG_PRINT("exit", ("error: %d", args.err));
3549
DBUG_RETURN(args.err);
3329
DRIZZLE_STORAGE_ENGINE_PLUGIN, &args);
3570
3351
Estimated cost of 'index only' scan
3573
double handler::index_only_read_time(uint keynr, double records)
3354
double handler::index_only_read_time(uint32_t keynr, double records)
3575
3356
double read_time;
3576
uint keys_per_block= (stats.block_size/2/
3357
uint32_t keys_per_block= (stats.block_size/2/
3577
3358
(table->key_info[keynr].key_length + ref_length) + 1);
3578
3359
read_time=((double) (records + keys_per_block-1) /
3579
3360
(double) keys_per_block);
3616
3397
contain scan parameters.
3620
handler::multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq,
3621
void *seq_init_param, uint n_ranges_arg,
3622
uint *bufsz, uint *flags, COST_VECT *cost)
3401
handler::multi_range_read_info_const(uint32_t keyno, RANGE_SEQ_IF *seq,
3402
void *seq_init_param,
3403
uint32_t n_ranges_arg __attribute__((unused)),
3404
uint32_t *bufsz, uint32_t *flags, COST_VECT *cost)
3624
3406
KEY_MULTI_RANGE range;
3625
3407
range_seq_t seq_it;
3626
3408
ha_rows rows, total_rows= 0;
3409
uint32_t n_ranges=0;
3628
3410
THD *thd= current_thd;
3630
3412
/* Default MRR implementation doesn't need buffer */
3707
3489
other Error or can't perform the requested scan
3710
int handler::multi_range_read_info(uint keyno, uint n_ranges, uint n_rows,
3711
uint *bufsz, uint *flags, COST_VECT *cost)
3492
int handler::multi_range_read_info(uint32_t keyno, uint32_t n_ranges, uint32_t n_rows,
3493
uint32_t *bufsz, uint32_t *flags, COST_VECT *cost)
3713
3495
*bufsz= 0; /* Default implementation doesn't need a buffer */
3771
3553
handler::multi_range_read_init(RANGE_SEQ_IF *seq_funcs, void *seq_init_param,
3772
uint n_ranges, uint mode, HANDLER_BUFFER *buf)
3554
uint32_t n_ranges, uint32_t mode,
3555
HANDLER_BUFFER *buf __attribute__((unused)))
3774
DBUG_ENTER("handler::multi_range_read_init");
3775
3557
mrr_iter= seq_funcs->init(seq_init_param, n_ranges, mode);
3776
3558
mrr_funcs= *seq_funcs;
3777
3559
mrr_is_output_sorted= test(mode & HA_MRR_SORTED);
3778
mrr_have_range= FALSE;
3560
mrr_have_range= false;
3874
3654
int DsMrr_impl::dsmrr_init(handler *h, KEY *key,
3875
3655
RANGE_SEQ_IF *seq_funcs, void *seq_init_param,
3876
uint n_ranges, uint mode, HANDLER_BUFFER *buf)
3656
uint32_t n_ranges, uint32_t mode, HANDLER_BUFFER *buf)
3880
3660
Item *pushed_cond= NULL;
3881
3661
handler *new_h2;
3882
DBUG_ENTER("DsMrr_impl::dsmrr_init");
3883
3662
keyno= h->active_index;
3884
DBUG_ASSERT(h2 == NULL);
3885
3664
if (mode & HA_MRR_USE_DEFAULT_IMPL || mode & HA_MRR_SORTED)
3887
use_default_impl= TRUE;
3888
DBUG_RETURN(h->handler::multi_range_read_init(seq_funcs, seq_init_param,
3666
use_default_impl= true;
3667
return(h->handler::multi_range_read_init(seq_funcs, seq_init_param,
3889
3668
n_ranges, mode, buf));
3891
3670
rowids_buf= buf->buffer;
3922
3701
table->prepare_for_position();
3923
3702
new_h2->extra(HA_EXTRA_KEYREAD);
3925
if (h2->ha_index_init(keyno, FALSE) ||
3704
if (h2->ha_index_init(keyno, false) ||
3926
3705
h2->handler::multi_range_read_init(seq_funcs, seq_init_param, n_ranges,
3929
use_default_impl= FALSE;
3708
use_default_impl= false;
3931
3710
if (pushed_cond)
3932
3711
h2->idx_cond_push(keyno, pushed_cond);
3941
3720
buf->end_of_used_area= rowids_buf_last;
3943
if (h->ha_rnd_init(FALSE))
3722
if (h->ha_rnd_init(false))
3948
3727
h2->ha_index_or_rnd_end();
3949
3728
h2->ha_external_lock(thd, F_UNLCK);
3956
3735
void DsMrr_impl::dsmrr_close()
3958
DBUG_ENTER("DsMrr_impl::dsmrr_close");
3961
3739
h2->ha_external_lock(current_thd, F_UNLCK);
3966
use_default_impl= TRUE;
3744
use_default_impl= true;
3971
static int rowid_cmp(void *h, uchar *a, uchar *b)
3749
static int rowid_cmp(void *h, unsigned char *a, unsigned char *b)
3973
3751
return ((handler*)h)->cmp_ref(a, b);
3991
3769
@retval other Error
3994
int DsMrr_impl::dsmrr_fill_buffer(handler *unused)
3772
int DsMrr_impl::dsmrr_fill_buffer(handler *unused __attribute__((unused)))
3996
3774
char *range_info;
3998
DBUG_ENTER("DsMrr_impl::dsmrr_fill_buffer");
4000
3777
rowids_buf_cur= rowids_buf;
4001
3778
while ((rowids_buf_cur < rowids_buf_end) &&
4016
3793
if (res && res != HA_ERR_END_OF_FILE)
4018
3795
dsmrr_eof= test(res == HA_ERR_END_OF_FILE);
4020
3797
/* Sort the buffer contents by rowid */
4021
uint elem_size= h->ref_length + (int)is_mrr_assoc * sizeof(void*);
4022
uint n_rowids= (rowids_buf_cur - rowids_buf) / elem_size;
3798
uint32_t elem_size= h->ref_length + (int)is_mrr_assoc * sizeof(void*);
3799
uint32_t n_rowids= (rowids_buf_cur - rowids_buf) / elem_size;
4024
3801
my_qsort2(rowids_buf, n_rowids, elem_size, (qsort2_cmp)rowid_cmp,
4026
3803
rowids_buf_last= rowids_buf_cur;
4027
3804
rowids_buf_cur= rowids_buf;
4078
3855
DS-MRR implementation: multi_range_read_info() function
4080
int DsMrr_impl::dsmrr_info(uint keyno, uint n_ranges, uint rows, uint *bufsz,
4081
uint *flags, COST_VECT *cost)
3857
int DsMrr_impl::dsmrr_info(uint32_t keyno, uint32_t n_ranges, uint32_t rows, uint32_t *bufsz,
3858
uint32_t *flags, COST_VECT *cost)
4084
uint def_flags= *flags;
4085
uint def_bufsz= *bufsz;
3861
uint32_t def_flags= *flags;
3862
uint32_t def_bufsz= *bufsz;
4087
3864
/* Get cost/flags/mem_usage of default MRR implementation */
4088
3865
res= h->handler::multi_range_read_info(keyno, n_ranges, rows, &def_bufsz,
4089
3866
&def_flags, cost);
4092
3869
if ((*flags & HA_MRR_USE_DEFAULT_IMPL) ||
4093
3870
choose_mrr_impl(keyno, rows, &def_flags, &def_bufsz, cost))
4095
3872
/* Default implementation is choosen */
4096
DBUG_PRINT("info", ("Default MRR implementation choosen"));
4097
3873
*flags= def_flags;
4098
3874
*bufsz= def_bufsz;
4102
DBUG_PRINT("info", ("DS-MRR implementation choosen"));
4109
3881
DS-MRR Implementation: multi_range_read_info_const() function
4112
ha_rows DsMrr_impl::dsmrr_info_const(uint keyno, RANGE_SEQ_IF *seq,
4113
void *seq_init_param, uint n_ranges,
4114
uint *bufsz, uint *flags, COST_VECT *cost)
3884
ha_rows DsMrr_impl::dsmrr_info_const(uint32_t keyno, RANGE_SEQ_IF *seq,
3885
void *seq_init_param, uint32_t n_ranges,
3886
uint32_t *bufsz, uint32_t *flags, COST_VECT *cost)
4117
uint def_flags= *flags;
4118
uint def_bufsz= *bufsz;
3889
uint32_t def_flags= *flags;
3890
uint32_t def_bufsz= *bufsz;
4119
3891
/* Get cost/flags/mem_usage of default MRR implementation */
4120
3892
rows= h->handler::multi_range_read_info_const(keyno, seq, seq_init_param,
4121
3893
n_ranges, &def_bufsz,
4134
3906
if ((*flags & HA_MRR_USE_DEFAULT_IMPL) ||
4135
3907
choose_mrr_impl(keyno, rows, flags, bufsz, cost))
4137
DBUG_PRINT("info", ("Default MRR implementation choosen"));
4138
3909
*flags= def_flags;
4139
3910
*bufsz= def_bufsz;
4143
3914
*flags &= ~HA_MRR_USE_DEFAULT_IMPL;
4144
DBUG_PRINT("info", ("DS-MRR implementation choosen"));
4161
3931
Allow use of DS-MRR in cases where the index has partially-covered
4162
3932
components but they are not used for scanning.
4168
bool DsMrr_impl::key_uses_partial_cols(uint keyno)
3938
bool DsMrr_impl::key_uses_partial_cols(uint32_t keyno)
4170
3940
KEY_PART_INFO *kp= table->key_info[keyno].key_part;
4171
3941
KEY_PART_INFO *kp_end= kp + table->key_info[keyno].key_parts;
4172
3942
for (; kp != kp_end; kp++)
4174
3944
if (!kp->field->part_of_key.is_set(keyno))
4197
3967
OUT If DS-MRR is choosen, cost of DS-MRR scan
4198
3968
else the value is not modified
4200
@retval TRUE Default MRR implementation should be used
4201
@retval FALSE DS-MRR implementation should be used
3970
@retval true Default MRR implementation should be used
3971
@retval false DS-MRR implementation should be used
4204
bool DsMrr_impl::choose_mrr_impl(uint keyno, ha_rows rows, uint *flags,
4205
uint *bufsz, COST_VECT *cost)
3974
bool DsMrr_impl::choose_mrr_impl(uint32_t keyno, ha_rows rows, uint32_t *flags,
3975
uint32_t *bufsz, COST_VECT *cost)
4207
3977
COST_VECT dsmrr_cost;
4216
3986
/* Use the default implementation */
4217
3987
*flags |= HA_MRR_USE_DEFAULT_IMPL;
4221
uint add_len= table->key_info[keyno].key_length + h->ref_length;
3991
uint32_t add_len= table->key_info[keyno].key_length + h->ref_length;
4222
3992
*bufsz -= add_len;
4223
3993
if (get_disk_sweep_mrr_cost(keyno, rows, *flags, bufsz, &dsmrr_cost))
4225
3995
*bufsz += add_len;
4227
3997
bool force_dsmrr;
4240
4010
*flags &= ~HA_MRR_USE_DEFAULT_IMPL; /* Use the DS-MRR implementation */
4241
4011
*flags &= ~HA_MRR_SORTED; /* We will return unordered output */
4242
4012
*cost= dsmrr_cost;
4247
4017
/* Use the default MRR implementation */
4254
static void get_sort_and_sweep_cost(TABLE *table, ha_rows nrows, COST_VECT *cost);
4024
static void get_sort_and_sweep_cost(Table *table, ha_rows nrows, COST_VECT *cost);
4263
4033
@param buffer_size INOUT Buffer size
4264
4034
@param cost OUT The cost
4267
@retval TRUE Error, DS-MRR cannot be used (the buffer is too small
4037
@retval true Error, DS-MRR cannot be used (the buffer is too small
4268
4038
for even 1 rowid)
4271
bool DsMrr_impl::get_disk_sweep_mrr_cost(uint keynr, ha_rows rows, uint flags,
4272
uint *buffer_size, COST_VECT *cost)
4041
bool DsMrr_impl::get_disk_sweep_mrr_cost(uint32_t keynr, ha_rows rows, uint32_t flags,
4042
uint32_t *buffer_size, COST_VECT *cost)
4274
ulong max_buff_entries, elem_size;
4044
uint32_t max_buff_entries, elem_size;
4275
4045
ha_rows rows_in_full_step, rows_in_last_step;
4046
uint32_t n_full_steps;
4277
4047
double index_read_cost;
4279
4049
elem_size= h->ref_length + sizeof(void*) * (!test(flags & HA_MRR_NO_ASSOCIATION));
4280
4050
max_buff_entries = *buffer_size / elem_size;
4282
4052
if (!max_buff_entries)
4283
return TRUE; /* Buffer has not enough space for even 1 rowid */
4053
return true; /* Buffer has not enough space for even 1 rowid */
4285
4055
/* Number of iterations we'll make with full buffer */
4286
4056
n_full_steps= (uint)floor(rows2double(rows) / max_buff_entries);
4305
*buffer_size= max(*buffer_size,
4075
*buffer_size= cmax((ulong)*buffer_size,
4306
4076
(size_t)(1.2*rows_in_last_step) * elem_size +
4307
4077
h->ref_length + table->key_info[keynr].key_length);
4342
void get_sort_and_sweep_cost(TABLE *table, ha_rows nrows, COST_VECT *cost)
4112
void get_sort_and_sweep_cost(Table *table, ha_rows nrows, COST_VECT *cost)
4346
get_sweep_read_cost(table, nrows, FALSE, cost);
4116
get_sweep_read_cost(table, nrows, false, cost);
4347
4117
/* Add cost of qsort call: n * log2(n) * cost(rowid_comparison) */
4348
4118
double cmp_op= rows2double(nrows) * (1.0 / TIME_FOR_COMPARE_ROWID);
4349
4119
if (cmp_op < 3)
4394
4164
@param table Table to be accessed
4395
4165
@param nrows Number of rows to retrieve
4396
@param interrupted TRUE <=> Assume that the disk sweep will be
4397
interrupted by other disk IO. FALSE - otherwise.
4166
@param interrupted true <=> Assume that the disk sweep will be
4167
interrupted by other disk IO. false - otherwise.
4398
4168
@param cost OUT The cost.
4401
void get_sweep_read_cost(TABLE *table, ha_rows nrows, bool interrupted,
4171
void get_sweep_read_cost(Table *table, ha_rows nrows, bool interrupted,
4402
4172
COST_VECT *cost)
4404
DBUG_ENTER("get_sweep_read_cost");
4407
4175
if (table->file->primary_key_is_clustered())
4414
4182
double n_blocks=
4415
ceil(ulonglong2double(table->file->stats.data_file_length) / IO_SIZE);
4183
ceil(uint64_t2double(table->file->stats.data_file_length) / IO_SIZE);
4416
4184
double busy_blocks=
4417
4185
n_blocks * (1.0 - pow(1.0 - 1.0/n_blocks, rows2double(nrows)));
4418
4186
if (busy_blocks < 1.0)
4419
4187
busy_blocks= 1.0;
4421
DBUG_PRINT("info",("sweep: nblocks=%g, busy_blocks=%g", n_blocks,
4423
4189
cost->io_count= busy_blocks;
4425
4191
if (!interrupted)
4459
4224
int handler::read_range_first(const key_range *start_key,
4460
4225
const key_range *end_key,
4461
4226
bool eq_range_arg,
4462
bool sorted /* ignored */)
4227
bool sorted __attribute__((unused)))
4465
DBUG_ENTER("handler::read_range_first");
4467
4231
eq_range= eq_range_arg;
4483
4247
start_key->keypart_map,
4484
4248
start_key->flag);
4486
DBUG_RETURN((result == HA_ERR_KEY_NOT_FOUND)
4250
return((result == HA_ERR_KEY_NOT_FOUND)
4487
4251
? HA_ERR_END_OF_FILE
4490
DBUG_RETURN (compare_key(end_range) <= 0 ? 0 : HA_ERR_END_OF_FILE);
4254
return (compare_key(end_range) <= 0 ? 0 : HA_ERR_END_OF_FILE);
4507
4271
int handler::read_range_next()
4510
DBUG_ENTER("handler::read_range_next");
4514
4277
/* We trust that index_next_same always gives a row in range */
4515
DBUG_RETURN(index_next_same(table->record[0],
4278
return(index_next_same(table->record[0],
4516
4279
end_range->key,
4517
4280
end_range->length));
4519
4282
result= index_next(table->record[0]);
4521
DBUG_RETURN(result);
4522
DBUG_RETURN(compare_key(end_range) <= 0 ? 0 : HA_ERR_END_OF_FILE);
4285
return(compare_key(end_range) <= 0 ? 0 : HA_ERR_END_OF_FILE);
4569
int handler::index_read_idx_map(uchar * buf, uint index, const uchar * key,
4332
int handler::index_read_idx_map(unsigned char * buf, uint32_t index, const unsigned char * key,
4570
4333
key_part_map keypart_map,
4571
4334
enum ha_rkey_function find_flag)
4592
4355
pointer pointer to TYPELIB structure
4594
static my_bool exts_handlerton(THD *unused, plugin_ref plugin,
4357
static bool exts_handlerton(THD *unused __attribute__((unused)),
4597
4361
List<char> *found_exts= (List<char> *) arg;
4598
4362
handlerton *hton= plugin_data(plugin, handlerton *);
4630
4394
known_extensions_id= mysys_usage_id;
4632
4396
plugin_foreach(NULL, exts_handlerton,
4633
MYSQL_STORAGE_ENGINE_PLUGIN, &found_exts);
4397
DRIZZLE_STORAGE_ENGINE_PLUGIN, &found_exts);
4635
4399
ext= (const char **) my_once_alloc(sizeof(char *)*
4636
4400
(found_exts.elements+1),
4637
4401
MYF(MY_WME | MY_FAE));
4639
DBUG_ASSERT(ext != 0);
4640
4404
known_extensions.count= found_exts.elements;
4641
4405
known_extensions.type_names= ext;
4652
static bool stat_print(THD *thd, const char *type, uint type_len,
4653
const char *file, uint file_len,
4654
const char *status, uint status_len)
4416
static bool stat_print(THD *thd, const char *type, uint32_t type_len,
4417
const char *file, uint32_t file_len,
4418
const char *status, uint32_t status_len)
4656
4420
Protocol *protocol= thd->protocol;
4657
4421
protocol->prepare_for_resend();
4659
4423
protocol->store(file, file_len, system_charset_info);
4660
4424
protocol->store(status, status_len, system_charset_info);
4661
4425
if (protocol->write())
4666
4430
bool ha_show_status(THD *thd, handlerton *db_type, enum ha_stat_type stat)
4676
4440
if (protocol->send_fields(&field_list,
4677
4441
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
4680
4444
result= db_type->show_status &&
4681
4445
db_type->show_status(db_type, thd, stat_print, stat) ? 1 : 0;
4698
4462
- table is not mysql.event
4701
static bool check_table_binlog_row_based(THD *thd, TABLE *table)
4465
static bool check_table_binlog_row_based(THD *thd, Table *table)
4703
4467
if (table->s->cached_row_logging_check == -1)
4707
4471
table->s->cached_row_logging_check= check;
4710
DBUG_ASSERT(table->s->cached_row_logging_check == 0 ||
4474
assert(table->s->cached_row_logging_check == 0 ||
4711
4475
table->s->cached_row_logging_check == 1);
4713
4477
return (thd->current_stmt_binlog_row_based &&
4739
4503
static int write_locked_table_maps(THD *thd)
4741
DBUG_ENTER("write_locked_table_maps");
4742
DBUG_PRINT("enter", ("thd: 0x%lx thd->lock: 0x%lx thd->locked_tables: 0x%lx "
4743
"thd->extra_lock: 0x%lx",
4744
(long) thd, (long) thd->lock,
4745
(long) thd->locked_tables, (long) thd->extra_lock));
4747
4505
if (thd->get_binlog_table_maps() == 0)
4749
MYSQL_LOCK *locks[3];
4507
DRIZZLE_LOCK *locks[3];
4750
4508
locks[0]= thd->extra_lock;
4751
4509
locks[1]= thd->lock;
4752
4510
locks[2]= thd->locked_tables;
4753
for (uint i= 0 ; i < sizeof(locks)/sizeof(*locks) ; ++i )
4511
for (uint32_t i= 0 ; i < sizeof(locks)/sizeof(*locks) ; ++i )
4755
MYSQL_LOCK const *const lock= locks[i];
4513
DRIZZLE_LOCK const *const lock= locks[i];
4756
4514
if (lock == NULL)
4759
TABLE **const end_ptr= lock->table + lock->table_count;
4760
for (TABLE **table_ptr= lock->table ;
4517
Table **const end_ptr= lock->table + lock->table_count;
4518
for (Table **table_ptr= lock->table ;
4761
4519
table_ptr != end_ptr ;
4764
TABLE *const table= *table_ptr;
4765
DBUG_PRINT("info", ("Checking table %s", table->s->table_name.str));
4522
Table *const table= *table_ptr;
4766
4523
if (table->current_lock == F_WRLCK &&
4767
4524
check_table_binlog_row_based(thd, table))
4773
4530
roll back the transaction.
4775
4532
if (unlikely(error))
4785
typedef bool Log_func(THD*, TABLE*, bool, const uchar*, const uchar*);
4542
typedef bool Log_func(THD*, Table*, bool, const unsigned char*, const unsigned char*);
4787
static int binlog_log_row(TABLE* table,
4788
const uchar *before_record,
4789
const uchar *after_record,
4544
static int binlog_log_row(Table* table,
4545
const unsigned char *before_record,
4546
const unsigned char *after_record,
4790
4547
Log_func *log_func)
4792
4549
if (table->no_replicate)
4797
4554
if (check_table_binlog_row_based(thd, table))
4799
DBUG_DUMP("read_set 10", (uchar*) table->read_set->bitmap,
4800
(table->s->fields + 7) / 8);
4802
4557
If there are no table maps written to the binary log, this is
4803
4558
the first row handled in this statement. In that case, we need
4815
4570
int handler::ha_external_lock(THD *thd, int lock_type)
4817
DBUG_ENTER("handler::ha_external_lock");
4819
4573
Whether this is lock or unlock, this should be true, and is to verify that
4820
4574
if get_auto_increment() was called (thus may have reserved intervals or
4821
4575
taken a table lock), ha_release_auto_increment() was too.
4823
DBUG_ASSERT(next_insert_id == 0);
4577
assert(next_insert_id == 0);
4826
4580
We cache the table flags if the locking succeeded. Otherwise, we
4827
4581
keep them as they were when they were fetched in ha_open().
4829
MYSQL_EXTERNAL_LOCK(lock_type);
4583
DRIZZLE_EXTERNAL_LOCK(lock_type);
4831
4585
int error= external_lock(thd, lock_type);
4832
4586
if (error == 0)
4833
4587
cached_table_flags= table_flags();
4841
4595
int handler::ha_reset()
4843
DBUG_ENTER("ha_reset");
4844
4597
/* Check that we have called all proper deallocation functions */
4845
DBUG_ASSERT((uchar*) table->def_read_set.bitmap +
4598
assert((unsigned char*) table->def_read_set.bitmap +
4846
4599
table->s->column_bitmap_size ==
4847
(uchar*) table->def_write_set.bitmap);
4848
DBUG_ASSERT(bitmap_is_set_all(&table->s->all_set));
4849
DBUG_ASSERT(table->key_read == 0);
4600
(unsigned char*) table->def_write_set.bitmap);
4601
assert(bitmap_is_set_all(&table->s->all_set));
4602
assert(table->key_read == 0);
4850
4603
/* ensure that ha_index_end / ha_rnd_end has been called */
4851
DBUG_ASSERT(inited == NONE);
4604
assert(inited == NONE);
4852
4605
/* Free cache used by filesort */
4853
4606
free_io_cache(table);
4854
4607
/* reset the bitmaps to point to defaults */
4855
4608
table->default_column_bitmaps();
4856
DBUG_RETURN(reset());
4860
int handler::ha_write_row(uchar *buf)
4613
int handler::ha_write_row(unsigned char *buf)
4863
4616
Log_func *log_func= Write_rows_log_event::binlog_row_logging_function;
4864
DBUG_ENTER("handler::ha_write_row");
4865
MYSQL_INSERT_ROW_START();
4617
DRIZZLE_INSERT_ROW_START();
4867
4619
mark_trx_read_write();
4869
4621
if (unlikely(error= write_row(buf)))
4871
4623
if (unlikely(error= binlog_log_row(table, 0, buf, log_func)))
4872
DBUG_RETURN(error); /* purecov: inspected */
4873
MYSQL_INSERT_ROW_END();
4624
return(error); /* purecov: inspected */
4625
DRIZZLE_INSERT_ROW_END();
4878
int handler::ha_update_row(const uchar *old_data, uchar *new_data)
4630
int handler::ha_update_row(const unsigned char *old_data, unsigned char *new_data)
4881
4633
Log_func *log_func= Update_rows_log_event::binlog_row_logging_function;