12
12
You should have received a copy of the GNU General Public License
13
13
along with this program; if not, write to the Free Software
14
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
28
28
#include "drizzled/errmsg_print.h"
29
29
#include "drizzled/gettext.h"
30
30
#include "drizzled/session.h"
31
#include "drizzled/plugin.h"
31
#include "drizzled/set_var.h"
32
#include <drizzled/plugin.h>
32
33
#include "drizzled/plugin/client.h"
33
34
#include "drizzled/table.h"
34
35
#include "drizzled/field/timestamp.h"
60
59
static uint32_t myisam_key_cache_division_limit;
61
60
static uint32_t myisam_key_cache_age_threshold;
62
61
static uint64_t max_sort_file_size;
63
typedef constrained_check<size_t, SIZE_MAX, 1024, 1024> sort_buffer_constraint;
64
static sort_buffer_constraint sort_buffer_size;
62
static uint64_t sort_buffer_size;
66
64
void st_mi_isam_share::setKeyCache()
128
126
const TableIdentifier &identifier,
129
127
message::Table &table_message);
129
/* Temp only engine, so do not return values. */
130
void doGetTableNames(CachedDirectory &, const SchemaIdentifier &, set<string>&) { };
131
132
uint32_t max_supported_keys() const { return MI_MAX_KEY; }
132
133
uint32_t max_supported_key_length() const { return MI_MAX_KEY_LENGTH; }
133
134
uint32_t max_supported_key_part_length() const { return MI_MAX_KEY_LENGTH; }
145
146
void doGetTableIdentifiers(drizzled::CachedDirectory &directory,
146
147
const drizzled::SchemaIdentifier &schema_identifier,
147
drizzled::TableIdentifier::vector &set_of_identifiers);
148
drizzled::TableIdentifiers &set_of_identifiers);
148
149
bool validateCreateTableOption(const std::string &key, const std::string &state)
160
161
void MyisamEngine::doGetTableIdentifiers(drizzled::CachedDirectory&,
161
162
const drizzled::SchemaIdentifier&,
162
drizzled::TableIdentifier::vector&)
163
drizzled::TableIdentifiers&)
166
167
bool MyisamEngine::doDoesTableExist(Session &session, const TableIdentifier &identifier)
168
return session.getMessageCache().doesTableMessageExist(identifier);
169
return session.doesTableMessageExist(identifier);
171
172
int MyisamEngine::doGetTableDefinition(Session &session,
172
173
const TableIdentifier &identifier,
173
174
message::Table &table_message)
175
if (session.getMessageCache().getTableMessage(identifier, table_message))
176
if (session.getTableMessage(identifier, table_message))
479
480
volatile int *killed_ptr(MI_CHECK *param)
481
482
/* In theory Unsafe conversion, but should be ok for now */
482
return (int*) (((Session *)(param->session))->getKilledPtr());
483
return (int*) &(((Session *)(param->session))->killed);
485
486
void mi_check_print_error(MI_CHECK *param, const char *fmt,...)
569
570
/* Name is here without an extension */
570
int ha_myisam::doOpen(const drizzled::TableIdentifier &identifier, int mode, uint32_t test_if_locked)
571
int ha_myisam::open(const char *name, int mode, uint32_t test_if_locked)
572
573
MI_KEYDEF *keyinfo;
573
574
MI_COLUMNDEF *recinfo= 0;
589
590
open of a table that is in use by other threads already (if the
590
591
MyISAM share exists already).
592
if (!(file= mi_open(identifier, mode, test_if_locked)))
593
if (!(file=mi_open(name, mode, test_if_locked)))
593
594
return (errno ? errno : -1);
595
if (!getTable()->getShare()->getType()) /* No need to perform a check for tmp table */
596
if (!table->getShare()->getType()) /* No need to perform a check for tmp table */
597
if ((errno= table2myisam(getTable(), &keyinfo, &recinfo, &recs)))
598
if ((errno= table2myisam(table, &keyinfo, &recinfo, &recs)))
601
if (check_definition(keyinfo, recinfo, getTable()->getShare()->sizeKeys(), recs,
602
if (check_definition(keyinfo, recinfo, table->getShare()->sizeKeys(), recs,
602
603
file->s->keyinfo, file->s->rec,
603
604
file->s->base.keys, file->s->base.fields, true))
614
615
info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST);
615
616
if (!(test_if_locked & HA_OPEN_WAIT_IF_LOCKED))
616
617
mi_extra(file, HA_EXTRA_WAIT_LOCK, 0);
617
if (!getTable()->getShare()->db_record_offset)
618
if (!table->getShare()->db_record_offset)
618
619
is_ordered= false;
621
622
keys_with_parts.reset();
622
for (i= 0; i < getTable()->getShare()->sizeKeys(); i++)
623
for (i= 0; i < table->getShare()->sizeKeys(); i++)
624
getTable()->key_info[i].block_size= file->s->keyinfo[i].block_length;
625
table->key_info[i].block_size= file->s->keyinfo[i].block_length;
626
KeyPartInfo *kp= getTable()->key_info[i].key_part;
627
KeyPartInfo *kp_end= kp + getTable()->key_info[i].key_parts;
627
KeyPartInfo *kp= table->key_info[i].key_part;
628
KeyPartInfo *kp_end= kp + table->key_info[i].key_parts;
628
629
for (; kp != kp_end; kp++)
630
631
if (!kp->field->part_of_key.test(i))
661
662
If we have an auto_increment column and we are writing a changed row
662
663
or a new row, then update the auto_increment value in the record.
664
if (getTable()->next_number_field && buf == getTable()->getInsertRecord())
665
if (table->next_number_field && buf == table->getInsertRecord())
667
668
if ((error= update_auto_increment()))
694
695
errmsg_printf(ERRMSG_LVL_INFO, "Retrying repair of: '%s' failed. "
695
696
"Please try REPAIR EXTENDED or myisamchk",
696
getTable()->getShare()->getPath());
697
table->getShare()->getPath());
697
698
return(HA_ADMIN_FAILED);
700
param.db_name= getTable()->getShare()->getSchemaName();
701
param.table_name= getTable()->getAlias();
701
param.db_name= table->getShare()->getSchemaName();
702
param.table_name= table->getAlias();
702
703
param.tmpfile_createflag = O_RDWR | O_TRUNC;
703
704
param.using_global_keycache = 1;
704
705
param.session= session;
705
706
param.out_flag= 0;
706
param.sort_buffer_length= static_cast<size_t>(sort_buffer_size);
707
param.sort_buffer_length= (size_t)sort_buffer_size;
707
708
strcpy(fixed_name,file->filename);
709
710
// Don't lock tables if we have used LOCK Table
710
if (mi_lock_database(file, getTable()->getShare()->getType() ? F_EXTRA_LCK : F_WRLCK))
711
if (mi_lock_database(file, table->getShare()->getType() ? F_EXTRA_LCK : F_WRLCK))
712
713
mi_check_print_error(¶m,ER(ER_CANT_LOCK),errno);
713
714
return(HA_ADMIN_FAILED);
905
906
else if (mode == HA_KEY_SWITCH_NONUNIQ_SAVE)
907
Session *session= getTable()->in_use;
908
boost::scoped_ptr<MI_CHECK> param_ap(new MI_CHECK);
909
MI_CHECK ¶m= *param_ap.get();
908
Session *session= table->in_use;
910
910
const char *save_proc_info= session->get_proc_info();
911
911
session->set_proc_info("Creating index");
912
912
myisamchk_init(¶m);
914
914
param.testflag= (T_SILENT | T_REP_BY_SORT | T_QUICK |
915
915
T_CREATE_MISSING_KEYS);
916
916
param.myf_rw&= ~MY_WAIT_IF_FULL;
917
param.sort_buffer_length= static_cast<size_t>(sort_buffer_size);
917
param.sort_buffer_length= (size_t)sort_buffer_size;
918
918
param.stats_method= MI_STATS_METHOD_NULLS_NOT_EQUAL;
919
919
if ((error= (repair(session,param,0) != HA_ADMIN_OK)) && param.retry_repair)
1066
1066
assert(inited==INDEX);
1067
1067
ha_statistic_increment(&system_status_var::ha_read_key_count);
1068
1068
int error=mi_rkey(file, buf, active_index, key, keypart_map, find_flag);
1069
getTable()->status=error ? STATUS_NOT_FOUND: 0;
1069
table->status=error ? STATUS_NOT_FOUND: 0;
1077
1077
ha_statistic_increment(&system_status_var::ha_read_key_count);
1078
1078
int error=mi_rkey(file, buf, index, key, keypart_map, find_flag);
1079
getTable()->status=error ? STATUS_NOT_FOUND: 0;
1079
table->status=error ? STATUS_NOT_FOUND: 0;
1087
1087
ha_statistic_increment(&system_status_var::ha_read_key_count);
1088
1088
int error=mi_rkey(file, buf, active_index, key, keypart_map,
1089
1089
HA_READ_PREFIX_LAST);
1090
getTable()->status=error ? STATUS_NOT_FOUND: 0;
1090
table->status=error ? STATUS_NOT_FOUND: 0;
1217
1217
if (flag & HA_STATUS_CONST)
1219
TableShare *share= getTable()->getMutableShare();
1219
TableShare *share= table->getMutableShare();
1220
1220
stats.max_data_file_length= misam_info.max_data_file_length;
1221
1221
stats.max_index_file_length= misam_info.max_index_file_length;
1222
1222
stats.create_time= misam_info.create_time;
1273
1273
share->keys_for_keyread&= share->keys_in_use;
1274
1274
share->db_record_offset= misam_info.record_offset;
1275
1275
if (share->key_parts)
1276
memcpy(getTable()->key_info[0].rec_per_key,
1276
memcpy(table->key_info[0].rec_per_key,
1277
1277
misam_info.rec_per_key,
1278
sizeof(getTable()->key_info[0].rec_per_key)*share->key_parts);
1278
sizeof(table->key_info[0].rec_per_key)*share->key_parts);
1279
1279
assert(share->getType() != message::Table::STANDARD);
1396
1396
int MyisamEngine::doRenameTable(Session &session, const TableIdentifier &from, const TableIdentifier &to)
1398
session.getMessageCache().renameTableMessage(from, to);
1398
session.renameTableMessage(from, to);
1400
1400
return mi_rename(from.getPath().c_str(), to.getPath().c_str());
1412
1412
unsigned char key[MI_MAX_KEY_LENGTH];
1414
if (!getTable()->getShare()->next_number_key_offset)
1414
if (!table->getShare()->next_number_key_offset)
1415
1415
{ // Autoincrement at key-start
1416
1416
ha_myisam::info(HA_STATUS_AUTO);
1417
1417
*first_value= stats.auto_increment_value;
1423
1423
/* it's safe to call the following if bulk_insert isn't on */
1424
mi_flush_bulk_insert(file, getTable()->getShare()->next_number_index);
1424
mi_flush_bulk_insert(file, table->getShare()->next_number_index);
1426
1426
(void) extra(HA_EXTRA_KEYREAD);
1427
key_copy(key, getTable()->getInsertRecord(),
1428
&getTable()->key_info[getTable()->getShare()->next_number_index],
1429
getTable()->getShare()->next_number_key_offset);
1430
error= mi_rkey(file, getTable()->getUpdateRecord(), (int) getTable()->getShare()->next_number_index,
1431
key, make_prev_keypart_map(getTable()->getShare()->next_number_keypart),
1427
key_copy(key, table->getInsertRecord(),
1428
&table->key_info[table->getShare()->next_number_index],
1429
table->getShare()->next_number_key_offset);
1430
error= mi_rkey(file, table->getUpdateRecord(), (int) table->getShare()->next_number_index,
1431
key, make_prev_keypart_map(table->getShare()->next_number_keypart),
1432
1432
HA_READ_PREFIX_LAST);
1437
1437
/* Get data from getUpdateRecord() */
1438
nr= ((uint64_t) getTable()->next_number_field->
1439
val_int_offset(getTable()->getShare()->rec_buff_length)+1);
1438
nr= ((uint64_t) table->next_number_field->
1439
val_int_offset(table->getShare()->rec_buff_length)+1);
1441
1441
extra(HA_EXTRA_NO_KEYREAD);
1442
1442
*first_value= nr;
1487
1487
return (uint)file->state->checksum;
1490
static MyisamEngine *engine= NULL;
1490
1492
static int myisam_init(module::Context &context)
1492
context.add(new MyisamEngine(engine_name));
1493
context.registerVariable(new sys_var_constrained_value<size_t>("sort-buffer-size",
1495
context.registerVariable(new sys_var_uint64_t_ptr("max_sort_file_size",
1496
&max_sort_file_size,
1497
context.getOptions()["max-sort-file-size"].as<uint64_t>()));
1494
const module::option_map &vm= context.getOptions();
1496
if (vm.count("max-sort-file-size"))
1498
if (max_sort_file_size > UINT64_MAX)
1500
errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for max-sort-file-size\n"));
1505
if (vm.count("sort-buffer-size"))
1507
if (sort_buffer_size < 1024 || sort_buffer_size > SIZE_MAX)
1509
errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for sort-buffer-size\n"));
1514
engine= new MyisamEngine(engine_name);
1515
context.add(engine);
1521
static DRIZZLE_SYSVAR_ULONGLONG(max_sort_file_size, max_sort_file_size,
1522
PLUGIN_VAR_RQCMDARG,
1523
N_("Don't use the fast sort index method to created index if the temporary file would get bigger than this."),
1524
NULL, NULL, INT32_MAX, 0, UINT64_MAX, 0);
1526
static DRIZZLE_SYSVAR_ULONGLONG(sort_buffer_size, sort_buffer_size,
1527
PLUGIN_VAR_RQCMDARG,
1528
N_("The buffer that is allocated when sorting the index when doing a REPAIR or when creating indexes with CREATE INDEX or ALTER TABLE."),
1529
NULL, NULL, 8192*1024, 1024, SIZE_MAX, 0);
1503
1531
static void init_options(drizzled::module::option_context &context)
1505
1533
context("max-sort-file-size",
1506
1534
po::value<uint64_t>(&max_sort_file_size)->default_value(INT32_MAX),
1507
1535
N_("Don't use the fast sort index method to created index if the temporary file would get bigger than this."));
1508
1536
context("sort-buffer-size",
1509
po::value<sort_buffer_constraint>(&sort_buffer_size)->default_value(8192*1024),
1537
po::value<uint64_t>(&sort_buffer_size)->default_value(8192*1024),
1510
1538
N_("The buffer that is allocated when sorting the index when doing a REPAIR or when creating indexes with CREATE INDEX or ALTER TABLE."));
1541
static drizzle_sys_var* sys_variables[]= {
1542
DRIZZLE_SYSVAR(max_sort_file_size),
1543
DRIZZLE_SYSVAR(sort_buffer_size),
1514
1548
DRIZZLE_DECLARE_PLUGIN
1520
1554
"Default engine as of MySQL 3.23 with great performance",
1521
1555
PLUGIN_LICENSE_GPL,
1522
1556
myisam_init, /* Plugin Init */
1523
NULL, /* system variables */
1557
sys_variables, /* system variables */
1524
1558
init_options /* config options */
1526
1560
DRIZZLE_DECLARE_PLUGIN_END;