19
19
Handler-calling-functions
22
#include <drizzled/server_includes.h>
22
#ifdef USE_PRAGMA_IMPLEMENTATION
23
#pragma implementation // gcc: Class implementation
26
#include "mysql_priv.h"
23
27
#include "rpl_filter.h"
24
#include <drizzled/drizzled_error_messages.h>
28
#include <myisampack.h>
27
32
While we have legacy_db_type, we have this array to
35
40
#define BITMAP_STACKBUF_SIZE (128/8)
37
KEY_CREATE_INFO default_key_create_info= { HA_KEY_ALG_UNDEF, 0, {NULL,0}, {NULL,0} };
42
KEY_CREATE_INFO default_key_create_info= { HA_KEY_ALG_UNDEF, 0, {NullS,0}, {NullS,0} };
39
44
/* number of entries in handlertons[] */
40
45
uint32_t total_ha= 0;
48
53
{ C_STRING_WITH_LEN("INNOBASE") }, { C_STRING_WITH_LEN("INNODB") },
49
54
{ C_STRING_WITH_LEN("HEAP") }, { C_STRING_WITH_LEN("MEMORY") },
53
58
const char *ha_row_type[] = {
57
62
const char *tx_isolation_names[] =
58
63
{ "READ-UNCOMMITTED", "READ-COMMITTED", "REPEATABLE-READ", "SERIALIZABLE",
60
65
TYPELIB tx_isolation_typelib= {array_elements(tx_isolation_names)-1,"",
61
66
tx_isolation_names, NULL};
63
68
static TYPELIB known_extensions= {0,"known_exts", NULL, NULL};
64
uint32_t known_extensions_id= 0;
69
uint known_extensions_id= 0;
110
115
/* my_strnncoll is a macro and gcc doesn't do early expansion of macro */
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))
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))
114
119
return ha_default_plugin(thd);
116
if ((plugin= my_plugin_lock_by_name(thd, name, DRIZZLE_STORAGE_ENGINE_PLUGIN)))
121
if ((plugin= my_plugin_lock_by_name(thd, name, MYSQL_STORAGE_ENGINE_PLUGIN)))
118
123
handlerton *hton= plugin_data(plugin, handlerton *);
119
124
if (!(hton->flags & HTON_NOT_USER_SELECTABLE))
131
136
for (table_alias= sys_table_aliases; table_alias->str; table_alias+= 2)
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))
138
if (!my_strnncoll(&my_charset_latin1,
139
(const uchar *)name->str, name->length,
140
(const uchar *)table_alias->str, table_alias->length))
137
142
name= table_alias + 1;
299
311
/* Allocate a pointer array for the error message strings. */
300
312
if (! (errmsgs= my_error_unregister(HA_ERR_FIRST, HA_ERR_LAST)))
302
free((unsigned char*) errmsgs);
314
my_free((uchar*) errmsgs, MYF(0));
322
if (hton && plugin->plugin->deinit)
323
(void)plugin->plugin->deinit(hton);
335
hton->panic(hton, HA_PANIC_CLOSE);
325
free((unsigned char*)hton);
337
my_free((uchar*)hton, MYF(0));
341
353
structure. Apparently get_backup_engine was not NULL even though it was
344
memset(hton, 0, sizeof(hton));
356
bzero(hton, sizeof(hton));
345
357
/* Historical Requirement */
346
358
plugin->data= hton; // shortcut for the future
347
359
if (plugin->plugin->init)
349
361
if (plugin->plugin->init(hton))
351
sql_print_error(_("Plugin '%s' init function returned error."),
363
sql_print_error("Plugin '%s' init function returned error.",
352
364
plugin->name.str);
377
389
if (idx == (int) DB_TYPE_DEFAULT)
379
sql_print_warning(_("Too many storage engines!"));
391
sql_print_warning("Too many storage engines!");
382
394
if (hton->db_type != DB_TYPE_UNKNOWN)
383
sql_print_warning(_("Storage engine '%s' has conflicting typecode. "
384
"Assigning value %d."), plugin->plugin->name, idx);
395
sql_print_warning("Storage engine '%s' has conflicting typecode. "
396
"Assigning value %d.", plugin->plugin->name, idx);
385
397
hton->db_type= (enum legacy_db_type) idx;
387
399
installed_htons[hton->db_type]= hton;
405
417
"memory" hton which will be configurable longterm. We should be able to
406
418
remove partition and myisammrg.
408
if (strcmp(plugin->plugin->name, "MEMORY") == 0)
420
switch (hton->db_type) {
411
if (strcmp(plugin->plugin->name, "MyISAM") == 0)
412
425
myisam_hton= hton;
460
477
void ha_drop_database(char* path)
462
plugin_foreach(NULL, dropdb_handlerton, DRIZZLE_STORAGE_ENGINE_PLUGIN, path);
479
plugin_foreach(NULL, dropdb_handlerton, MYSQL_STORAGE_ENGINE_PLUGIN, path);
466
483
static bool closecon_handlerton(THD *thd, plugin_ref plugin,
467
void *unused __attribute__((unused)))
484
void *unused __attribute__((__unused__)))
469
486
handlerton *hton= plugin_data(plugin, handlerton *);
485
502
void ha_close_connection(THD* thd)
487
plugin_foreach(thd, closecon_handlerton, DRIZZLE_STORAGE_ENGINE_PLUGIN, 0);
504
plugin_foreach(thd, closecon_handlerton, MYSQL_STORAGE_ENGINE_PLUGIN, 0);
490
507
/* ========================================================================
760
777
to maintain atomicity: if CREATE TABLE .. SELECT failed,
761
778
the newly created table is deleted.
762
779
In addition, some DDL statements issue interim transaction
763
commits: e.g. ALTER Table issues a commit after data is copied
780
commits: e.g. ALTER TABLE issues a commit after data is copied
764
781
from the original table to the internal temporary table. Other
765
782
statements, e.g. CREATE TABLE ... SELECT do not always commit
767
784
And finally there is a group of DDL statements such as
768
RENAME/DROP Table that doesn't start a new transaction
785
RENAME/DROP TABLE that doesn't start a new transaction
769
786
and doesn't commit.
771
788
This diversity makes it hard to say what will happen if
853
push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
870
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
854
871
ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
855
872
ha_resolve_storage_engine_name(ht));
950
967
assert(thd->transaction.stmt.ha_list == NULL ||
951
968
trans == &thd->transaction.stmt);
970
if (thd->in_sub_stmt)
973
Since we don't support nested statement transactions in 5.0,
974
we can't commit or rollback stmt transactions while we are inside
975
stored functions or triggers. So we simply do nothing now.
976
TODO: This should be fixed in later ( >= 5.1) releases.
981
We assume that all statements which commit or rollback main transaction
982
are prohibited inside of stored functions or triggers. So they should
983
bail out with error even before ha_commit_trans() call. To be 100% safe
984
let us throw error in non-debug builds.
987
my_error(ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0));
1068
1105
assert(thd->transaction.stmt.ha_list == NULL ||
1069
1106
trans == &thd->transaction.stmt);
1108
if (thd->in_sub_stmt)
1111
If we are inside stored function or trigger we should not commit or
1112
rollback current statement transaction. See comment in ha_commit_trans()
1113
call for more information.
1118
my_error(ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0));
1073
1123
for (; ha_info; ha_info= ha_info_next)
1108
1158
if (is_real_trans && thd->transaction.all.modified_non_trans_table &&
1109
1159
!thd->slave_thread && thd->killed != THD::KILL_CONNECTION)
1110
push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
1160
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
1111
1161
ER_WARNING_NOT_COMPLETE_ROLLBACK,
1112
1162
ER(ER_WARNING_NOT_COMPLETE_ROLLBACK));
1185
1235
xaop.result= 1;
1187
1237
plugin_foreach(NULL, commit ? xacommit_handlerton : xarollback_handlerton,
1188
DRIZZLE_STORAGE_ENGINE_PLUGIN, &xaop);
1238
MYSQL_STORAGE_ENGINE_PLUGIN, &xaop);
1190
1240
return xaop.result;
1227
1277
while ((got= hton->recover(hton, info->list, info->len)) > 0 )
1229
sql_print_information(_("Found %d prepared transaction(s) in %s"),
1279
sql_print_information("Found %d prepared transaction(s) in %s",
1230
1280
got, ha_resolve_storage_engine_name(hton));
1231
1281
for (int i=0; i < got; i ++)
1245
1295
// recovery mode
1246
1296
if (info->commit_list ?
1247
hash_search(info->commit_list, (unsigned char *)&x, sizeof(x)) != 0 :
1297
hash_search(info->commit_list, (uchar *)&x, sizeof(x)) != 0 :
1248
1298
tc_heuristic_recover == TC_HEURISTIC_RECOVER_COMMIT)
1250
1300
hton->commit_by_xid(hton, info->list+i);
1308
1358
plugin_foreach(NULL, xarecover_handlerton,
1309
DRIZZLE_STORAGE_ENGINE_PLUGIN, &info);
1359
MYSQL_STORAGE_ENGINE_PLUGIN, &info);
1311
free((unsigned char*)info.list);
1361
my_free((uchar*)info.list, MYF(0));
1312
1362
if (info.found_foreign_xids)
1313
sql_print_warning(_("Found %d prepared XA transactions"),
1363
sql_print_warning("Found %d prepared XA transactions",
1314
1364
info.found_foreign_xids);
1315
1365
if (info.dry_run && info.found_my_xids)
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."),
1367
sql_print_error("Found %d prepared transactions! It means that mysqld was "
1368
"not shut down properly last time and critical recovery "
1369
"information (last binlog or %s file) was manually deleted "
1370
"after a crash. You have to start mysqld with "
1371
"--tc-heuristic-recover switch to commit or rollback "
1372
"pending transactions.",
1323
1373
info.found_my_xids, opt_tc_log_file);
1326
1376
if (info.commit_list)
1327
sql_print_information(_("Crash recovery finished."));
1377
sql_print_information("Crash recovery finished.");
1397
1447
static bool release_temporary_latches(THD *thd, plugin_ref plugin,
1398
void *unused __attribute__((unused)))
1448
void *unused __attribute__((__unused__)))
1400
1450
handlerton *hton= plugin_data(plugin, handlerton *);
1409
1459
int ha_release_temporary_latches(THD *thd)
1411
plugin_foreach(thd, release_temporary_latches, DRIZZLE_STORAGE_ENGINE_PLUGIN,
1461
plugin_foreach(thd, release_temporary_latches, MYSQL_STORAGE_ENGINE_PLUGIN,
1417
1467
int ha_rollback_to_savepoint(THD *thd, SAVEPOINT *sv)
1420
THD_TRANS *trans= &thd->transaction.all;
1470
THD_TRANS *trans= (thd->in_sub_stmt ? &thd->transaction.stmt :
1471
&thd->transaction.all);
1421
1472
Ha_trx_info *ha_info, *ha_info_next;
1423
1474
trans->no_2pc=0;
1433
1484
assert(ht->savepoint_set != 0);
1434
1485
if ((err= ht->savepoint_rollback(ht, thd,
1435
(unsigned char *)(sv+1)+ht->savepoint_offset)))
1486
(uchar *)(sv+1)+ht->savepoint_offset)))
1436
1487
{ // cannot happen
1437
1488
my_error(ER_ERROR_DURING_ROLLBACK, MYF(0), err);
1451
1502
handlerton *ht= ha_info->ht();
1452
if ((err= ht->rollback(ht, thd, !(0))))
1503
if ((err= ht->rollback(ht, thd, !thd->in_sub_stmt)))
1453
1504
{ // cannot happen
1454
1505
my_error(ER_ERROR_DURING_ROLLBACK, MYF(0), err);
1471
1522
int ha_savepoint(THD *thd, SAVEPOINT *sv)
1474
THD_TRANS *trans= &thd->transaction.all;
1525
THD_TRANS *trans= (thd->in_sub_stmt ? &thd->transaction.stmt :
1526
&thd->transaction.all);
1475
1527
Ha_trx_info *ha_info= trans->ha_list;
1476
1528
for (; ha_info; ha_info= ha_info->next())
1487
if ((err= ht->savepoint_set(ht, thd, (unsigned char *)(sv+1)+ht->savepoint_offset)))
1539
if ((err= ht->savepoint_set(ht, thd, (uchar *)(sv+1)+ht->savepoint_offset)))
1488
1540
{ // cannot happen
1489
1541
my_error(ER_GET_ERRNO, MYF(0), err);
1513
1565
if (!ht->savepoint_release)
1515
1567
if ((err= ht->savepoint_release(ht, thd,
1516
(unsigned char *)(sv+1) + ht->savepoint_offset)))
1568
(uchar *)(sv+1) + ht->savepoint_offset)))
1517
1569
{ // cannot happen
1518
1570
my_error(ER_GET_ERRNO, MYF(0), err);
1540
1592
bool warn= true;
1542
plugin_foreach(thd, snapshot_handlerton, DRIZZLE_STORAGE_ENGINE_PLUGIN, &warn);
1594
plugin_foreach(thd, snapshot_handlerton, MYSQL_STORAGE_ENGINE_PLUGIN, &warn);
1545
1597
Same idea as when one wants to CREATE TABLE in one engine which does not
1549
push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
1601
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
1550
1602
"This MySQL server does not support any "
1551
1603
"consistent-read capable storage engine");
1556
static bool flush_handlerton(THD *thd __attribute__((unused)),
1608
static bool flush_handlerton(THD *thd __attribute__((__unused__)),
1557
1609
plugin_ref plugin,
1558
void *arg __attribute__((unused)))
1610
void *arg __attribute__((__unused__)))
1560
1612
handlerton *hton= plugin_data(plugin, handlerton *);
1561
1613
if (hton->state == SHOW_OPTION_YES && hton->flush_logs &&
1570
1622
if (db_type == NULL)
1572
1624
if (plugin_foreach(NULL, flush_handlerton,
1573
DRIZZLE_STORAGE_ENGINE_PLUGIN, 0))
1625
MYSQL_STORAGE_ENGINE_PLUGIN, 0))
1610
1662
struct Ha_delete_table_error_handler: public Internal_error_handler
1613
virtual bool handle_error(uint32_t sql_errno,
1665
virtual bool handle_error(uint sql_errno,
1614
1666
const char *message,
1615
DRIZZLE_ERROR::enum_warning_level level,
1667
MYSQL_ERROR::enum_warning_level level,
1617
char buff[DRIZZLE_ERRMSG_SIZE];
1669
char buff[MYSQL_ERRMSG_SIZE];
1622
1674
Ha_delete_table_error_handler::
1623
handle_error(uint32_t sql_errno __attribute__((unused)),
1675
handle_error(uint sql_errno __attribute__((__unused__)),
1624
1676
const char *message,
1625
DRIZZLE_ERROR::enum_warning_level level __attribute__((unused)),
1626
THD *thd __attribute__((unused)))
1677
MYSQL_ERROR::enum_warning_level level __attribute__((__unused__)),
1678
THD *thd __attribute__((__unused__)))
1628
1680
/* Grab the error message */
1629
1681
strmake(buff, message, sizeof(buff)-1);
1642
1694
char tmp_path[FN_REFLEN];
1645
1697
TABLE_SHARE dummy_share;
1647
memset(&dummy_table, 0, sizeof(dummy_table));
1648
memset(&dummy_share, 0, sizeof(dummy_share));
1699
bzero((char*) &dummy_table, sizeof(dummy_table));
1700
bzero((char*) &dummy_share, sizeof(dummy_share));
1649
1701
dummy_table.s= &dummy_share;
1651
/* DB_TYPE_UNKNOWN is used in ALTER Table when renaming only .frm files */
1703
/* DB_TYPE_UNKNOWN is used in ALTER TABLE when renaming only .frm files */
1652
1704
if (table_type == NULL ||
1653
1705
! (file=get_new_handler((TABLE_SHARE*)0, thd->mem_root, table_type)))
1654
1706
return(ENOENT);
1684
1736
XXX: should we convert *all* errors to warnings here?
1685
1737
What if the error is fatal?
1687
push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_ERROR, error,
1739
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, error,
1688
1740
ha_delete_table_error_handler.buff);
1702
1754
on this->table->mem_root and we will not be able to reclaim that memory
1703
1755
when the clone handler object is destroyed.
1705
if (!(new_handler->ref= (unsigned char*) alloc_root(mem_root, ALIGN_SIZE(ref_length)*2)))
1757
if (!(new_handler->ref= (uchar*) alloc_root(mem_root, ALIGN_SIZE(ref_length)*2)))
1707
1759
if (new_handler && !new_handler->ha_open(table,
1708
1760
table->s->normalized_path.str,
1710
1762
HA_OPEN_IGNORE_IF_LOCKED))
1711
1763
return new_handler;
1736
1788
Try O_RDONLY if cannot open as O_RDWR
1737
1789
Don't wait for locks if not HA_OPEN_WAIT_IF_LOCKED is set
1739
int handler::ha_open(Table *table_arg, const char *name, int mode,
1791
int handler::ha_open(TABLE *table_arg, const char *name, int mode,
1740
1792
int test_if_locked)
1765
1817
(void) extra(HA_EXTRA_NO_READCHECK); // Not needed in SQL
1767
1819
/* ref is already allocated for us if we're called from handler::clone() */
1768
if (!ref && !(ref= (unsigned char*) alloc_root(&table->mem_root,
1820
if (!ref && !(ref= (uchar*) alloc_root(&table->mem_root,
1769
1821
ALIGN_SIZE(ref_length)*2)))
1804
1856
This is never called for InnoDB tables, as these table types
1805
1857
has the HA_STATS_RECORDS_IS_EXACT set.
1807
int handler::read_first_row(unsigned char * buf, uint32_t primary_key)
1859
int handler::read_first_row(uchar * buf, uint primary_key)
1809
1861
register int error;
1992
2044
assert(next_insert_id >= auto_inc_interval_for_cur_row.minimum());
1994
if ((nr= table->next_number_field->val_int()) != 0)
2046
if (((nr= table->next_number_field->val_int()) != 0) ||
2047
(table->auto_increment_field_not_null && (thd->variables.sql_mode & MODE_NO_AUTO_VALUE_ON_ZERO)))
1997
2050
Update next_insert_id if we had already generated a value in this
2020
2073
handler::estimation_rows_to_insert was set by
2021
2074
handler::ha_start_bulk_insert(); if 0 it means "unknown".
2023
uint32_t nb_already_reserved_intervals=
2076
uint nb_already_reserved_intervals=
2024
2077
thd->auto_inc_intervals_in_cur_stmt_for_binlog.nb_elements();
2025
2078
uint64_t nb_desired_values;
2157
2210
@param first_value (OUT) the first value reserved by the handler
2158
2211
@param nb_reserved_values (OUT) how many values the handler reserved
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)),
2213
void handler::get_auto_increment(uint64_t offset __attribute__((__unused__)),
2214
uint64_t increment __attribute__((__unused__)),
2215
uint64_t nb_desired_values __attribute__((__unused__)),
2163
2216
uint64_t *first_value,
2164
2217
uint64_t *nb_reserved_values)
2186
unsigned char key[MAX_KEY_LENGTH];
2239
uchar key[MAX_KEY_LENGTH];
2187
2240
key_copy(key, table->record[0],
2188
2241
table->key_info + table->s->next_number_index,
2189
2242
table->s->next_number_key_offset);
2230
void handler::print_keydup_error(uint32_t key_nr, const char *msg)
2283
void handler::print_keydup_error(uint key_nr, const char *msg)
2232
2285
/* Write the duplicated key in the error message */
2233
2286
char key[MAX_KEY_LENGTH];
2244
2297
/* Table is opened and defined at this point */
2245
2298
key_unpack(&str,table,(uint) key_nr);
2246
uint32_t max_length=DRIZZLE_ERRMSG_SIZE-(uint) strlen(msg);
2299
uint max_length=MYSQL_ERRMSG_SIZE-(uint) strlen(msg);
2247
2300
if (str.length() >= max_length)
2249
2302
str.length(max_length-4);
2288
2341
case HA_ERR_FOUND_DUPP_KEY:
2290
uint32_t key_nr=get_dup_key(error);
2343
uint key_nr=get_dup_key(error);
2291
2344
if ((int) key_nr >= 0)
2293
2346
print_keydup_error(key_nr, ER(ER_DUP_ENTRY_WITH_KEY_NAME));
2299
2352
case HA_ERR_FOREIGN_DUPLICATE_KEY:
2301
uint32_t key_nr= get_dup_key(error);
2354
uint key_nr= get_dup_key(error);
2302
2355
if ((int) key_nr >= 0)
2304
uint32_t max_length;
2305
2358
/* Write the key in the error message */
2306
2359
char key[MAX_KEY_LENGTH];
2307
2360
String str(key,sizeof(key),system_charset_info);
2308
2361
/* Table is opened and defined at this point */
2309
2362
key_unpack(&str,table,(uint) key_nr);
2310
max_length= (DRIZZLE_ERRMSG_SIZE-
2363
max_length= (MYSQL_ERRMSG_SIZE-
2311
2364
(uint) strlen(ER(ER_FOREIGN_DUPLICATE_KEY)));
2312
2365
if (str.length() >= max_length)
2400
2453
case HA_ERR_DROP_INDEX_FK:
2402
2455
const char *ptr= "???";
2403
uint32_t key_nr= get_dup_key(error);
2456
uint key_nr= get_dup_key(error);
2404
2457
if ((int) key_nr >= 0)
2405
2458
ptr= table->key_info[key_nr].name;
2406
2459
my_error(ER_DROP_INDEX_FK, MYF(0), ptr);
2458
2511
Returns true if this is a temporary error
2460
bool handler::get_error_message(int error __attribute__((unused)),
2461
String* buf __attribute__((unused)))
2513
bool handler::get_error_message(int error __attribute__((__unused__)),
2514
String* buf __attribute__((__unused__)))
2483
2536
if (!keypart->fieldnr)
2485
2538
Field *field= table->field[keypart->fieldnr-1];
2486
if (field->type() == DRIZZLE_TYPE_BLOB)
2539
if (field->type() == MYSQL_TYPE_BLOB)
2488
2541
if (check_opt->sql_flags & TT_FOR_UPGRADE)
2489
2542
check_opt->flags= T_MEDIUM;
2515
2568
update frm version for temporary tables as this code doesn't support
2516
2569
temporary tables.
2518
if (table->s->mysql_version == DRIZZLE_VERSION_ID)
2571
if (table->s->mysql_version == MYSQL_VERSION_ID)
2521
strxmov(path, table->s->normalized_path.str, reg_ext, NULL);
2574
strxmov(path, table->s->normalized_path.str, reg_ext, NullS);
2523
if ((file= my_open(path, O_RDWR, MYF(MY_WME))) >= 0)
2576
if ((file= my_open(path, O_RDWR|O_BINARY, MYF(MY_WME))) >= 0)
2525
unsigned char version[4];
2526
2579
char *key= table->s->table_cache_key.str;
2527
uint32_t key_length= table->s->table_cache_key.length;
2580
uint key_length= table->s->table_cache_key.length;
2529
2582
HASH_SEARCH_STATE state;
2531
int4store(version, DRIZZLE_VERSION_ID);
2584
int4store(version, MYSQL_VERSION_ID);
2533
if (pwrite(file, (unsigned char*)version, 4, 51L) == 0)
2586
if (pwrite(file, (uchar*)version, 4, 51L) == 0)
2539
for (entry=(Table*) hash_first(&open_cache,(unsigned char*) key,key_length, &state);
2592
for (entry=(TABLE*) hash_first(&open_cache,(uchar*) key,key_length, &state);
2541
entry= (Table*) hash_next(&open_cache,(unsigned char*) key,key_length, &state))
2542
entry->s->mysql_version= DRIZZLE_VERSION_ID;
2594
entry= (TABLE*) hash_next(&open_cache,(uchar*) key,key_length, &state))
2595
entry->s->mysql_version= MYSQL_VERSION_ID;
2546
my_close(file,MYF(MY_WME));
2599
VOID(my_close(file,MYF(MY_WME)));
2547
2600
return(result);
2554
2607
key if error because of duplicated keys
2556
uint32_t handler::get_dup_key(int error)
2609
uint handler::get_dup_key(int error)
2558
2611
table->file->errkey = (uint) -1;
2559
2612
if (error == HA_ERR_FOUND_DUPP_KEY || error == HA_ERR_FOREIGN_DUPLICATE_KEY ||
2646
if ((table->s->mysql_version >= DRIZZLE_VERSION_ID) &&
2699
if ((table->s->mysql_version >= MYSQL_VERSION_ID) &&
2647
2700
(check_opt->sql_flags & TT_FOR_UPGRADE))
2650
if (table->s->mysql_version < DRIZZLE_VERSION_ID)
2703
if (table->s->mysql_version < MYSQL_VERSION_ID)
2652
2705
if ((error= check_old_types()))
2944
2997
Tell the storage engine that it is allowed to "disable transaction" in the
2945
2998
handler. It is a hint that ACID is not required - it is used in NDB for
2946
ALTER Table, for example, when data are copied to temporary table.
2999
ALTER TABLE, for example, when data are copied to temporary table.
2947
3000
A storage engine may treat this hint any way it likes. NDB for example
2948
3001
starts to commit every now and then automatically.
2949
3002
This hint can be safely ignored.
2969
int handler::index_next_same(unsigned char *buf, const unsigned char *key, uint32_t keylen)
3022
int handler::index_next_same(uchar *buf, const uchar *key, uint keylen)
2972
3025
if (!(error=index_next(buf)))
2974
3027
my_ptrdiff_t ptrdiff= buf - table->record[0];
2975
unsigned char *save_record_0= NULL;
3028
uchar *save_record_0= NULL;
2976
3029
KEY *key_info= NULL;
2977
3030
KEY_PART_INFO *key_part;
2978
3031
KEY_PART_INFO *key_part_end= NULL;
3049
3102
if (update_create_info)
3050
table.updateCreateInfo(create_info);
3103
update_create_info_from_table(create_info, &table);
3052
3105
name= check_lowercase_names(table.file, share.path.str, name_buff);
3054
3107
error= table.file->ha_create(name, &table, create_info);
3055
closefrm(&table, 0);
3108
VOID(closefrm(&table, 0));
3058
strxmov(name_buff, db, ".", table_name, NULL);
3111
strxmov(name_buff, db, ".", table_name, NullS);
3059
3112
my_error(ER_CANT_CREATE_TABLE, MYF(ME_BELL+ME_WAITTANG), name_buff, error);
3079
3132
int ha_create_table_from_engine(THD* thd, const char *db, const char *name)
3082
unsigned char *frmblob;
3084
3137
char path[FN_REFLEN];
3085
3138
HA_CREATE_INFO create_info;
3087
3140
TABLE_SHARE share;
3089
memset(&create_info, 0, sizeof(create_info));
3142
bzero((uchar*) &create_info,sizeof(create_info));
3090
3143
if ((error= ha_discover(thd, db, name, &frmblob, &frmlen)))
3092
3145
/* Table could not be discovered and thus not created */
3101
3154
build_table_filename(path, FN_REFLEN-1, db, name, "", 0);
3102
3155
// Save the frm file
3103
3156
error= writefrm(path, frmblob, frmlen);
3157
my_free(frmblob, MYF(0));
3119
table.updateCreateInfo(&create_info);
3172
update_create_info_from_table(&create_info, &table);
3120
3173
create_info.table_options|= HA_OPTION_CREATE_FROM_ENGINE;
3122
3175
check_lowercase_names(table.file, path, path);
3123
3176
error=table.file->ha_create(path, &table, &create_info);
3124
closefrm(&table, 1);
3177
VOID(closefrm(&table, 1));
3126
3179
return(error != 0);
3147
3200
Init a key cache if it has not been initied before.
3149
int ha_init_key_cache(const char *name __attribute__((unused)),
3202
int ha_init_key_cache(const char *name __attribute__((__unused__)),
3150
3203
KEY_CACHE *key_cache)
3152
3205
if (!key_cache->key_cache_inited)
3154
3207
pthread_mutex_lock(&LOCK_global_system_variables);
3155
3208
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;
3209
uint tmp_block_size= (uint) key_cache->param_block_size;
3210
uint division_limit= key_cache->param_division_limit;
3211
uint age_threshold= key_cache->param_age_threshold;
3159
3212
pthread_mutex_unlock(&LOCK_global_system_variables);
3160
3213
return(!init_key_cache(key_cache,
3161
3214
tmp_block_size,
3176
3229
pthread_mutex_lock(&LOCK_global_system_variables);
3177
3230
long tmp_buff_size= (long) key_cache->param_buff_size;
3178
3231
long tmp_block_size= (long) key_cache->param_block_size;
3179
uint32_t division_limit= key_cache->param_division_limit;
3180
uint32_t age_threshold= key_cache->param_age_threshold;
3232
uint division_limit= key_cache->param_division_limit;
3233
uint age_threshold= key_cache->param_age_threshold;
3181
3234
pthread_mutex_unlock(&LOCK_global_system_variables);
3182
3235
return(!resize_key_cache(key_cache, tmp_block_size,
3195
3248
if (key_cache->key_cache_inited)
3197
3250
pthread_mutex_lock(&LOCK_global_system_variables);
3198
uint32_t division_limit= key_cache->param_division_limit;
3199
uint32_t age_threshold= key_cache->param_age_threshold;
3251
uint division_limit= key_cache->param_division_limit;
3252
uint age_threshold= key_cache->param_age_threshold;
3200
3253
pthread_mutex_unlock(&LOCK_global_system_variables);
3201
3254
change_key_cache_param(key_cache, division_limit, age_threshold);
3258
3311
int ha_discover(THD *thd, const char *db, const char *name,
3259
unsigned char **frmblob, size_t *frmlen)
3312
uchar **frmblob, size_t *frmlen)
3261
3314
int error= -1; // Table does not exist in any handler
3262
3315
st_discover_args args= {db, name, frmblob, frmlen};
3267
3320
if (plugin_foreach(thd, discover_handlerton,
3268
DRIZZLE_STORAGE_ENGINE_PLUGIN, &args))
3321
MYSQL_STORAGE_ENGINE_PLUGIN, &args))
3327
3380
st_table_exists_in_engine_args args= {db, name, HA_ERR_NO_SUCH_TABLE};
3328
3381
plugin_foreach(thd, table_exists_in_engine_handlerton,
3329
DRIZZLE_STORAGE_ENGINE_PLUGIN, &args);
3382
MYSQL_STORAGE_ENGINE_PLUGIN, &args);
3330
3383
return(args.err);
3351
3404
Estimated cost of 'index only' scan
3354
double handler::index_only_read_time(uint32_t keynr, double records)
3407
double handler::index_only_read_time(uint keynr, double records)
3356
3409
double read_time;
3357
uint32_t keys_per_block= (stats.block_size/2/
3410
uint keys_per_block= (stats.block_size/2/
3358
3411
(table->key_info[keynr].key_length + ref_length) + 1);
3359
3412
read_time=((double) (records + keys_per_block-1) /
3360
3413
(double) keys_per_block);
3401
handler::multi_range_read_info_const(uint32_t keyno, RANGE_SEQ_IF *seq,
3454
handler::multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq,
3402
3455
void *seq_init_param,
3403
uint32_t n_ranges_arg __attribute__((unused)),
3404
uint32_t *bufsz, uint32_t *flags, COST_VECT *cost)
3456
uint n_ranges_arg __attribute__((__unused__)),
3457
uint *bufsz, uint *flags, COST_VECT *cost)
3406
3459
KEY_MULTI_RANGE range;
3407
3460
range_seq_t seq_it;
3408
3461
ha_rows rows, total_rows= 0;
3409
uint32_t n_ranges=0;
3410
3463
THD *thd= current_thd;
3412
3465
/* Default MRR implementation doesn't need buffer */
3489
3542
other Error or can't perform the requested scan
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)
3545
int handler::multi_range_read_info(uint keyno, uint n_ranges, uint n_rows,
3546
uint *bufsz, uint *flags, COST_VECT *cost)
3495
3548
*bufsz= 0; /* Default implementation doesn't need a buffer */
3553
3606
handler::multi_range_read_init(RANGE_SEQ_IF *seq_funcs, void *seq_init_param,
3554
uint32_t n_ranges, uint32_t mode,
3555
HANDLER_BUFFER *buf __attribute__((unused)))
3607
uint n_ranges, uint mode,
3608
HANDLER_BUFFER *buf __attribute__((__unused__)))
3557
3610
mrr_iter= seq_funcs->init(seq_init_param, n_ranges, mode);
3558
3611
mrr_funcs= *seq_funcs;
3654
3707
int DsMrr_impl::dsmrr_init(handler *h, KEY *key,
3655
3708
RANGE_SEQ_IF *seq_funcs, void *seq_init_param,
3656
uint32_t n_ranges, uint32_t mode, HANDLER_BUFFER *buf)
3709
uint n_ranges, uint mode, HANDLER_BUFFER *buf)
3660
3713
Item *pushed_cond= NULL;
3661
3714
handler *new_h2;
3662
3715
keyno= h->active_index;
3749
static int rowid_cmp(void *h, unsigned char *a, unsigned char *b)
3802
static int rowid_cmp(void *h, uchar *a, uchar *b)
3751
3804
return ((handler*)h)->cmp_ref(a, b);
3769
3822
@retval other Error
3772
int DsMrr_impl::dsmrr_fill_buffer(handler *unused __attribute__((unused)))
3825
int DsMrr_impl::dsmrr_fill_buffer(handler *unused __attribute__((__unused__)))
3774
3827
char *range_info;
3777
3830
rowids_buf_cur= rowids_buf;
3778
3831
while ((rowids_buf_cur < rowids_buf_end) &&
3795
3848
dsmrr_eof= test(res == HA_ERR_END_OF_FILE);
3797
3850
/* Sort the buffer contents by rowid */
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;
3851
uint elem_size= h->ref_length + (int)is_mrr_assoc * sizeof(void*);
3852
uint n_rowids= (rowids_buf_cur - rowids_buf) / elem_size;
3801
3854
my_qsort2(rowids_buf, n_rowids, elem_size, (qsort2_cmp)rowid_cmp,
3855
3908
DS-MRR implementation: multi_range_read_info() function
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)
3910
int DsMrr_impl::dsmrr_info(uint keyno, uint n_ranges, uint rows, uint *bufsz,
3911
uint *flags, COST_VECT *cost)
3861
uint32_t def_flags= *flags;
3862
uint32_t def_bufsz= *bufsz;
3914
uint def_flags= *flags;
3915
uint def_bufsz= *bufsz;
3864
3917
/* Get cost/flags/mem_usage of default MRR implementation */
3865
3918
res= h->handler::multi_range_read_info(keyno, n_ranges, rows, &def_bufsz,
3881
3934
DS-MRR Implementation: multi_range_read_info_const() function
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)
3937
ha_rows DsMrr_impl::dsmrr_info_const(uint keyno, RANGE_SEQ_IF *seq,
3938
void *seq_init_param, uint n_ranges,
3939
uint *bufsz, uint *flags, COST_VECT *cost)
3889
uint32_t def_flags= *flags;
3890
uint32_t def_bufsz= *bufsz;
3942
uint def_flags= *flags;
3943
uint def_bufsz= *bufsz;
3891
3944
/* Get cost/flags/mem_usage of default MRR implementation */
3892
3945
rows= h->handler::multi_range_read_info_const(keyno, seq, seq_init_param,
3893
3946
n_ranges, &def_bufsz,
3935
3988
@retval false No
3938
bool DsMrr_impl::key_uses_partial_cols(uint32_t keyno)
3991
bool DsMrr_impl::key_uses_partial_cols(uint keyno)
3940
3993
KEY_PART_INFO *kp= table->key_info[keyno].key_part;
3941
3994
KEY_PART_INFO *kp_end= kp + table->key_info[keyno].key_parts;
3971
4024
@retval false DS-MRR implementation should be used
3974
bool DsMrr_impl::choose_mrr_impl(uint32_t keyno, ha_rows rows, uint32_t *flags,
3975
uint32_t *bufsz, COST_VECT *cost)
4027
bool DsMrr_impl::choose_mrr_impl(uint keyno, ha_rows rows, uint *flags,
4028
uint *bufsz, COST_VECT *cost)
3977
4030
COST_VECT dsmrr_cost;
3991
uint32_t add_len= table->key_info[keyno].key_length + h->ref_length;
4044
uint add_len= table->key_info[keyno].key_length + h->ref_length;
3992
4045
*bufsz -= add_len;
3993
4046
if (get_disk_sweep_mrr_cost(keyno, rows, *flags, bufsz, &dsmrr_cost))
4038
4091
for even 1 rowid)
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)
4094
bool DsMrr_impl::get_disk_sweep_mrr_cost(uint keynr, ha_rows rows, uint flags,
4095
uint *buffer_size, COST_VECT *cost)
4044
4097
uint32_t max_buff_entries, elem_size;
4045
4098
ha_rows rows_in_full_step, rows_in_last_step;
4046
uint32_t n_full_steps;
4047
4100
double index_read_cost;
4049
4102
elem_size= h->ref_length + sizeof(void*) * (!test(flags & HA_MRR_NO_ASSOCIATION));
4075
*buffer_size= cmax((ulong)*buffer_size,
4128
*buffer_size= max(*buffer_size,
4076
4129
(size_t)(1.2*rows_in_last_step) * elem_size +
4077
4130
h->ref_length + table->key_info[keynr].key_length);
4168
4221
@param cost OUT The cost.
4171
void get_sweep_read_cost(Table *table, ha_rows nrows, bool interrupted,
4224
void get_sweep_read_cost(TABLE *table, ha_rows nrows, bool interrupted,
4172
4225
COST_VECT *cost)
4224
4277
int handler::read_range_first(const key_range *start_key,
4225
4278
const key_range *end_key,
4226
4279
bool eq_range_arg,
4227
bool sorted __attribute__((unused)))
4280
bool sorted __attribute__((__unused__)))
4332
int handler::index_read_idx_map(unsigned char * buf, uint32_t index, const unsigned char * key,
4385
int handler::index_read_idx_map(uchar * buf, uint index, const uchar * key,
4333
4386
key_part_map keypart_map,
4334
4387
enum ha_rkey_function find_flag)
4394
4447
known_extensions_id= mysys_usage_id;
4396
4449
plugin_foreach(NULL, exts_handlerton,
4397
DRIZZLE_STORAGE_ENGINE_PLUGIN, &found_exts);
4450
MYSQL_STORAGE_ENGINE_PLUGIN, &found_exts);
4399
4452
ext= (const char **) my_once_alloc(sizeof(char *)*
4400
4453
(found_exts.elements+1),
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)
4469
static bool stat_print(THD *thd, const char *type, uint type_len,
4470
const char *file, uint file_len,
4471
const char *status, uint status_len)
4420
4473
Protocol *protocol= thd->protocol;
4421
4474
protocol->prepare_for_resend();
4462
4515
- table is not mysql.event
4465
static bool check_table_binlog_row_based(THD *thd, Table *table)
4518
static bool check_table_binlog_row_based(THD *thd, TABLE *table)
4467
4520
if (table->s->cached_row_logging_check == -1)
4505
4558
if (thd->get_binlog_table_maps() == 0)
4507
DRIZZLE_LOCK *locks[3];
4560
MYSQL_LOCK *locks[3];
4508
4561
locks[0]= thd->extra_lock;
4509
4562
locks[1]= thd->lock;
4510
4563
locks[2]= thd->locked_tables;
4511
for (uint32_t i= 0 ; i < sizeof(locks)/sizeof(*locks) ; ++i )
4564
for (uint i= 0 ; i < sizeof(locks)/sizeof(*locks) ; ++i )
4513
DRIZZLE_LOCK const *const lock= locks[i];
4566
MYSQL_LOCK const *const lock= locks[i];
4514
4567
if (lock == NULL)
4517
Table **const end_ptr= lock->table + lock->table_count;
4518
for (Table **table_ptr= lock->table ;
4570
TABLE **const end_ptr= lock->table + lock->table_count;
4571
for (TABLE **table_ptr= lock->table ;
4519
4572
table_ptr != end_ptr ;
4522
Table *const table= *table_ptr;
4575
TABLE *const table= *table_ptr;
4523
4576
if (table->current_lock == F_WRLCK &&
4524
4577
check_table_binlog_row_based(thd, table))
4542
typedef bool Log_func(THD*, Table*, bool, const unsigned char*, const unsigned char*);
4595
typedef bool Log_func(THD*, TABLE*, bool, const uchar*, const uchar*);
4544
static int binlog_log_row(Table* table,
4545
const unsigned char *before_record,
4546
const unsigned char *after_record,
4597
static int binlog_log_row(TABLE* table,
4598
const uchar *before_record,
4599
const uchar *after_record,
4547
4600
Log_func *log_func)
4549
4602
if (table->no_replicate)
4580
4633
We cache the table flags if the locking succeeded. Otherwise, we
4581
4634
keep them as they were when they were fetched in ha_open().
4583
DRIZZLE_EXTERNAL_LOCK(lock_type);
4636
MYSQL_EXTERNAL_LOCK(lock_type);
4585
4638
int error= external_lock(thd, lock_type);
4586
4639
if (error == 0)
4595
4648
int handler::ha_reset()
4597
4650
/* Check that we have called all proper deallocation functions */
4598
assert((unsigned char*) table->def_read_set.bitmap +
4651
assert((uchar*) table->def_read_set.bitmap +
4599
4652
table->s->column_bitmap_size ==
4600
(unsigned char*) table->def_write_set.bitmap);
4653
(uchar*) table->def_write_set.bitmap);
4601
4654
assert(bitmap_is_set_all(&table->s->all_set));
4602
4655
assert(table->key_read == 0);
4603
4656
/* ensure that ha_index_end / ha_rnd_end has been called */
4613
int handler::ha_write_row(unsigned char *buf)
4666
int handler::ha_write_row(uchar *buf)
4616
4669
Log_func *log_func= Write_rows_log_event::binlog_row_logging_function;
4617
DRIZZLE_INSERT_ROW_START();
4670
MYSQL_INSERT_ROW_START();
4619
4672
mark_trx_read_write();
4623
4676
if (unlikely(error= binlog_log_row(table, 0, buf, log_func)))
4624
4677
return(error); /* purecov: inspected */
4625
DRIZZLE_INSERT_ROW_END();
4678
MYSQL_INSERT_ROW_END();
4630
int handler::ha_update_row(const unsigned char *old_data, unsigned char *new_data)
4683
int handler::ha_update_row(const uchar *old_data, uchar *new_data)
4633
4686
Log_func *log_func= Update_rows_log_event::binlog_row_logging_function;