14
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
18
#define DRIZZLE_SERVER 1
20
#include <drizzled/server_includes.h>
21
#include <mysys/my_bit.h>
17
#ifdef USE_PRAGMA_IMPLEMENTATION
18
#pragma implementation // gcc: Class implementation
21
#define MYSQL_SERVER 1
22
#include "mysql_priv.h"
23
#include <mysql/plugin.h>
22
26
#include <myisampack.h>
23
27
#include "ha_myisam.h"
24
29
#include "myisamdef.h"
25
#include <drizzled/drizzled_error_messages.h>
26
#include <drizzled/util/test.h>
28
31
ulong myisam_recover_options= HA_RECOVER_NONE;
30
33
/* bits in myisam_recover_options */
31
34
const char *myisam_recover_names[] =
32
{ "DEFAULT", "BACKUP", "FORCE", "QUICK", NULL};
35
{ "DEFAULT", "BACKUP", "FORCE", "QUICK", NullS};
33
36
TYPELIB myisam_recover_typelib= {array_elements(myisam_recover_names)-1,"",
34
37
myisam_recover_names, NULL};
36
39
const char *myisam_stats_method_names[] = {"nulls_unequal", "nulls_equal",
37
"nulls_ignored", NULL};
40
"nulls_ignored", NullS};
38
41
TYPELIB myisam_stats_method_typelib= {
39
42
array_elements(myisam_stats_method_names) - 1, "",
40
43
myisam_stats_method_names, NULL};
126
int table2myisam(Table *table_arg, MI_KEYDEF **keydef_out,
127
MI_COLUMNDEF **recinfo_out, uint32_t *records_out)
131
int table2myisam(TABLE *table_arg, MI_KEYDEF **keydef_out,
132
MI_COLUMNDEF **recinfo_out, uint *records_out)
129
uint32_t i, j, recpos, minpos, fieldpos, temp_length, length;
134
uint i, j, recpos, minpos, fieldpos, temp_length, length;
130
135
enum ha_base_keytype type= HA_KEYTYPE_BINARY;
131
unsigned char *record;
133
138
MI_KEYDEF *keydef;
134
139
MI_COLUMNDEF *recinfo, *recinfo_pos;
135
140
HA_KEYSEG *keyseg;
136
141
TABLE_SHARE *share= table_arg->s;
137
uint32_t options= share->db_options_in_use;
142
uint options= share->db_options_in_use;
143
DBUG_ENTER("table2myisam");
138
144
if (!(my_multi_malloc(MYF(MY_WME),
139
145
recinfo_out, (share->fields * 2 + 2) * sizeof(MI_COLUMNDEF),
140
146
keydef_out, share->keys * sizeof(MI_KEYDEF),
142
148
(share->key_parts + share->keys) * sizeof(HA_KEYSEG),
144
return(HA_ERR_OUT_OF_MEM); /* purecov: inspected */
150
DBUG_RETURN(HA_ERR_OUT_OF_MEM); /* purecov: inspected */
145
151
keydef= *keydef_out;
146
152
recinfo= *recinfo_out;
147
153
pos= table_arg->key_info;
148
154
for (i= 0; i < share->keys; i++, pos++)
150
keydef[i].flag= ((uint16_t) pos->flags & (HA_NOSAME));
151
keydef[i].key_alg= HA_KEY_ALG_BTREE;
156
keydef[i].flag= ((uint16) pos->flags & (HA_NOSAME | HA_FULLTEXT ));
157
keydef[i].key_alg= pos->algorithm == HA_KEY_ALG_UNDEF ? (HA_KEY_ALG_BTREE) : pos->algorithm;
152
158
keydef[i].block_length= pos->block_size;
153
159
keydef[i].seg= keyseg;
154
160
keydef[i].keysegs= pos->key_parts;
189
198
keydef[i].seg[j].null_bit= field->null_bit;
190
199
keydef[i].seg[j].null_pos= (uint) (field->null_ptr-
191
(unsigned char*) table_arg->record[0]);
200
(uchar*) table_arg->record[0]);
195
204
keydef[i].seg[j].null_bit= 0;
196
205
keydef[i].seg[j].null_pos= 0;
198
if (field->type() == DRIZZLE_TYPE_BLOB)
207
if (field->type() == MYSQL_TYPE_BLOB)
200
209
keydef[i].seg[j].flag|= HA_BLOB_PART;
201
210
/* save number of bytes used to pack length */
245
DBUG_PRINT("loop", ("found: 0x%lx recpos: %d minpos: %d length: %d",
246
(long) found, recpos, minpos, length));
236
247
if (recpos != minpos)
237
248
{ // Reserved space (Null bits?)
238
memset(recinfo_pos, 0, sizeof(*recinfo_pos));
249
bzero((char*) recinfo_pos, sizeof(*recinfo_pos));
239
250
recinfo_pos->type= (int) FIELD_NORMAL;
240
recinfo_pos++->length= (uint16_t) (minpos - recpos);
251
recinfo_pos++->length= (uint16) (minpos - recpos);
245
256
if (found->flags & BLOB_FLAG)
246
257
recinfo_pos->type= (int) FIELD_BLOB;
247
else if (found->type() == DRIZZLE_TYPE_VARCHAR)
258
else if (found->type() == MYSQL_TYPE_VARCHAR)
248
259
recinfo_pos->type= FIELD_VARCHAR;
249
260
else if (!(options & HA_OPTION_PACK_RECORD))
250
261
recinfo_pos->type= (int) FIELD_NORMAL;
251
262
else if (found->zero_pack())
252
263
recinfo_pos->type= (int) FIELD_SKIP_ZERO;
254
recinfo_pos->type= (int) ((length <= 3) ? FIELD_NORMAL : FIELD_SKIP_PRESPACE);
265
recinfo_pos->type= (int) ((length <= 3 ||
266
(found->flags & ZEROFILL_FLAG)) ?
268
found->type() == MYSQL_TYPE_STRING ||
269
found->type() == MYSQL_TYPE_VAR_STRING ?
270
FIELD_SKIP_ENDSPACE :
271
FIELD_SKIP_PRESPACE);
255
272
if (found->null_ptr)
257
274
recinfo_pos->null_bit= found->null_bit;
258
275
recinfo_pos->null_pos= (uint) (found->null_ptr -
259
(unsigned char*) table_arg->record[0]);
276
(uchar*) table_arg->record[0]);
263
280
recinfo_pos->null_bit= 0;
264
281
recinfo_pos->null_pos= 0;
266
(recinfo_pos++)->length= (uint16_t) length;
283
(recinfo_pos++)->length= (uint16) length;
267
284
recpos= minpos + length;
285
DBUG_PRINT("loop", ("length: %d type: %d",
286
recinfo_pos[-1].length,recinfo_pos[-1].type));
269
288
*records_out= (uint) (recinfo_pos - recinfo);
314
333
int check_definition(MI_KEYDEF *t1_keyinfo, MI_COLUMNDEF *t1_recinfo,
315
uint32_t t1_keys, uint32_t t1_recs,
334
uint t1_keys, uint t1_recs,
316
335
MI_KEYDEF *t2_keyinfo, MI_COLUMNDEF *t2_recinfo,
317
uint32_t t2_keys, uint32_t t2_recs, bool strict)
336
uint t2_keys, uint t2_recs, bool strict)
339
DBUG_ENTER("check_definition");
320
340
if ((strict ? t1_keys != t2_keys : t1_keys > t2_keys))
342
DBUG_PRINT("error", ("Number of keys differs: t1_keys=%u, t2_keys=%u",
324
346
if (t1_recs != t2_recs)
348
DBUG_PRINT("error", ("Number of recs differs: t1_recs=%u, t2_recs=%u",
328
352
for (i= 0; i < t1_keys; i++)
330
354
HA_KEYSEG *t1_keysegs= t1_keyinfo[i].seg;
331
355
HA_KEYSEG *t2_keysegs= t2_keyinfo[i].seg;
356
if (t1_keyinfo[i].flag & HA_FULLTEXT && t2_keyinfo[i].flag & HA_FULLTEXT)
358
else if (t1_keyinfo[i].flag & HA_FULLTEXT ||
359
t2_keyinfo[i].flag & HA_FULLTEXT)
361
DBUG_PRINT("error", ("Key %d has different definition", i));
362
DBUG_PRINT("error", ("t1_fulltext= %d, t2_fulltext=%d",
363
test(t1_keyinfo[i].flag & HA_FULLTEXT),
364
test(t2_keyinfo[i].flag & HA_FULLTEXT)));
367
if (t1_keyinfo[i].flag & HA_SPATIAL && t2_keyinfo[i].flag & HA_SPATIAL)
369
else if (t1_keyinfo[i].flag & HA_SPATIAL ||
370
t2_keyinfo[i].flag & HA_SPATIAL)
372
DBUG_PRINT("error", ("Key %d has different definition", i));
373
DBUG_PRINT("error", ("t1_spatial= %d, t2_spatial=%d",
374
test(t1_keyinfo[i].flag & HA_SPATIAL),
375
test(t2_keyinfo[i].flag & HA_SPATIAL)));
332
378
if (t1_keyinfo[i].keysegs != t2_keyinfo[i].keysegs ||
333
379
t1_keyinfo[i].key_alg != t2_keyinfo[i].key_alg)
381
DBUG_PRINT("error", ("Key %d has different definition", i));
382
DBUG_PRINT("error", ("t1_keysegs=%d, t1_key_alg=%d",
383
t1_keyinfo[i].keysegs, t1_keyinfo[i].key_alg));
384
DBUG_PRINT("error", ("t2_keysegs=%d, t2_key_alg=%d",
385
t2_keyinfo[i].keysegs, t2_keyinfo[i].key_alg));
337
388
for (j= t1_keyinfo[i].keysegs; j--;)
339
uint8_t t1_keysegs_j__type= t1_keysegs[j].type;
390
uint8 t1_keysegs_j__type= t1_keysegs[j].type;
342
393
Table migration from 4.1 to 5.1. In 5.1 a *TEXT key part is
360
411
t1_keysegs[j].null_bit != t2_keysegs[j].null_bit ||
361
412
t1_keysegs[j].length != t2_keysegs[j].length)
414
DBUG_PRINT("error", ("Key segment %d (key %d) has different "
415
"definition", j, i));
416
DBUG_PRINT("error", ("t1_type=%d, t1_language=%d, t1_null_bit=%d, "
418
t1_keysegs[j].type, t1_keysegs[j].language,
419
t1_keysegs[j].null_bit, t1_keysegs[j].length));
420
DBUG_PRINT("error", ("t2_type=%d, t2_language=%d, t2_null_bit=%d, "
422
t2_keysegs[j].type, t2_keysegs[j].language,
423
t2_keysegs[j].null_bit, t2_keysegs[j].length));
379
441
t1_rec->length != t2_rec->length ||
380
442
t1_rec->null_bit != t2_rec->null_bit)
444
DBUG_PRINT("error", ("Field %d has different definition", i));
445
DBUG_PRINT("error", ("t1_type=%d, t1_length=%d, t1_null_bit=%d",
446
t1_rec->type, t1_rec->length, t1_rec->null_bit));
447
DBUG_PRINT("error", ("t2_type=%d, t2_length=%d, t2_null_bit=%d",
448
t2_rec->type, t2_rec->length, t2_rec->null_bit));
452
520
sql_print_error("%s", message);
453
521
for (element= file->s->in_use; element; element= list_rest(element))
455
sql_print_error("%s", "Unknown thread accessing table");
523
THD *thd= (THD*) element->data;
524
sql_print_error("%s", thd ? thd_security_context(thd, buf, sizeof(buf), 0)
525
: "Unknown thread accessing table");
457
527
pthread_mutex_unlock(&file->s->intern_lock);
462
532
ha_myisam::ha_myisam(handlerton *hton, TABLE_SHARE *table_arg)
463
533
:handler(hton, table_arg), file(0),
464
int_table_flags(HA_NULL_IN_KEY |
465
HA_BINLOG_ROW_CAPABLE |
466
HA_BINLOG_STMT_CAPABLE |
473
HA_STATS_RECORDS_IS_EXACT |
474
HA_NEED_READ_RANGE_BUFFER |
534
int_table_flags(HA_NULL_IN_KEY | HA_CAN_FULLTEXT | HA_CAN_SQL_HANDLER |
535
HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE |
536
HA_DUPLICATE_POS | HA_CAN_INDEX_BLOBS | HA_AUTO_PART_KEY |
537
HA_FILE_BASED | HA_CAN_GEOMETRY | HA_NO_TRANSACTIONS |
538
HA_CAN_INSERT_DELAYED | HA_CAN_BIT_FIELD | HA_CAN_RTREEKEYS |
539
HA_HAS_RECORDS | HA_STATS_RECORDS_IS_EXACT |
540
HA_NEED_READ_RANGE_BUFFER | HA_MRR_CANT_SORT),
476
541
can_enable_indexes(1)
500
const char *ha_myisam::index_type(uint32_t key_number __attribute__((unused)))
565
const char *ha_myisam::index_type(uint key_number __attribute__((__unused__)))
505
570
/* Name is here without an extension */
506
int ha_myisam::open(const char *name, int mode, uint32_t test_if_locked)
571
int ha_myisam::open(const char *name, int mode, uint test_if_locked)
508
573
MI_KEYDEF *keyinfo;
509
574
MI_COLUMNDEF *recinfo= 0;
514
579
If the user wants to have memory mapped data files, add an
549
616
if (test_if_locked & (HA_OPEN_IGNORE_IF_LOCKED | HA_OPEN_TMP_TABLE))
550
mi_extra(file, HA_EXTRA_NO_WAIT_LOCK, 0);
617
VOID(mi_extra(file, HA_EXTRA_NO_WAIT_LOCK, 0));
552
619
info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST);
553
620
if (!(test_if_locked & HA_OPEN_WAIT_IF_LOCKED))
554
mi_extra(file, HA_EXTRA_WAIT_LOCK, 0);
621
VOID(mi_extra(file, HA_EXTRA_WAIT_LOCK, 0));
555
622
if (!table->s->db_record_offset)
556
623
int_table_flags|=HA_REC_NOT_IN_SEQ;
557
624
if (file->s->options & (HA_OPTION_CHECKSUM | HA_OPTION_COMPRESS_RECORD))
816
883
int ha_myisam::repair(THD *thd, MI_CHECK ¶m, bool do_optimize)
819
uint32_t local_testflag=param.testflag;
886
uint local_testflag=param.testflag;
820
887
bool optimize_done= !do_optimize, statistics_done=0;
821
const char *old_proc_info= thd->get_proc_info();
888
const char *old_proc_info=thd->proc_info;
822
889
char fixed_name[FN_REFLEN];
823
890
MYISAM_SHARE* share = file->s;
824
891
ha_rows rows= file->state->records;
892
DBUG_ENTER("ha_myisam::repair");
827
895
Normally this method is entered with a properly opened table. If the
847
915
param.tmpdir= &mysql_tmpdir_list;
848
916
param.out_flag= 0;
849
my_stpcpy(fixed_name,file->filename);
917
strmov(fixed_name,file->filename);
851
// Don't lock tables if we have used LOCK Table
919
// Don't lock tables if we have used LOCK TABLE
852
920
if (!thd->locked_tables &&
853
921
mi_lock_database(file, table->s->tmp_table ? F_EXTRA_LCK : F_WRLCK))
855
923
mi_check_print_error(¶m,ER(ER_CANT_LOCK),my_errno);
856
return(HA_ADMIN_FAILED);
924
DBUG_RETURN(HA_ADMIN_FAILED);
859
927
if (!do_optimize ||
877
945
/* TODO: respect myisam_repair_threads variable */
878
946
snprintf(buf, 40, "Repair with %d threads", my_count_bits(key_map));
879
thd->set_proc_info(buf);
947
thd_proc_info(thd, buf);
880
948
error = mi_repair_parallel(¶m, file, fixed_name,
881
949
param.testflag & T_QUICK);
882
thd->set_proc_info("Repair done"); // to reset proc_info, as
950
thd_proc_info(thd, "Repair done"); // to reset proc_info, as
883
951
// it was pointing to local buffer
887
thd->set_proc_info("Repair by sorting");
955
thd_proc_info(thd, "Repair by sorting");
888
956
error = mi_repair_by_sort(¶m, file, fixed_name,
889
957
param.testflag & T_QUICK);
894
thd->set_proc_info("Repair with keycache");
962
thd_proc_info(thd, "Repair with keycache");
895
963
param.testflag &= ~T_REP_BY_SORT;
896
964
error= mi_repair(¶m, file, fixed_name,
897
965
param.testflag & T_QUICK);
958
1026
file->update |= HA_STATE_CHANGED | HA_STATE_ROW_CHANGED;
959
1027
update_state_info(¶m, file, 0);
961
thd->set_proc_info(old_proc_info);
1029
thd_proc_info(thd, old_proc_info);
962
1030
if (!thd->locked_tables)
963
1031
mi_lock_database(file,F_UNLCK);
964
return(error ? HA_ADMIN_FAILED :
1032
DBUG_RETURN(error ? HA_ADMIN_FAILED :
965
1033
!optimize_done ? HA_ADMIN_ALREADY_DONE : HA_ADMIN_OK);
1183
1252
void ha_myisam::start_bulk_insert(ha_rows rows)
1254
DBUG_ENTER("ha_myisam::start_bulk_insert");
1185
1255
THD *thd= current_thd;
1186
ulong size= cmin(thd->variables.read_buff_size,
1256
ulong size= min(thd->variables.read_buff_size,
1187
1257
(ulong) (table->s->avg_row_length*rows));
1258
DBUG_PRINT("info",("start_bulk_insert: rows %lu size %lu",
1259
(ulong) rows, size));
1189
1261
/* don't enable row cache if too few rows */
1190
1262
if (! rows || (rows > MI_MIN_ROWS_TO_USE_WRITE_CACHE))
1193
1265
can_enable_indexes= mi_is_all_keys_active(file->s->state.key_map,
1194
1266
file->s->base.keys);
1197
Only disable old index if the table was empty and we are inserting
1199
We should not do this for only a few rows as this is slower and
1200
we don't want to update the key statistics based of only a few rows.
1202
if (file->state->records == 0 && can_enable_indexes &&
1203
(!rows || rows >= MI_MIN_ROWS_TO_DISABLE_INDEXES))
1204
mi_disable_non_unique_index(file,rows);
1268
if (!(specialflag & SPECIAL_SAFE_MODE))
1271
Only disable old index if the table was empty and we are inserting
1273
We should not do this for only a few rows as this is slower and
1274
we don't want to update the key statistics based of only a few rows.
1276
if (file->state->records == 0 && can_enable_indexes &&
1277
(!rows || rows >= MI_MIN_ROWS_TO_DISABLE_INDEXES))
1278
mi_disable_non_unique_index(file,rows);
1206
1280
if (!file->bulk_insert &&
1207
1281
(!rows || rows >= MI_MIN_ROWS_TO_USE_BULK_INSERT))
1209
1283
mi_init_bulk_insert(file, thd->variables.bulk_insert_buff_size, rows);
1288
1363
return mi_update(file,old_data,new_data);
1291
int ha_myisam::delete_row(const unsigned char *buf)
1366
int ha_myisam::delete_row(const uchar *buf)
1293
1368
ha_statistic_increment(&SSV::ha_delete_count);
1294
1369
return mi_delete(file,buf);
1301
bool index_cond_func_myisam(void *arg)
1374
my_bool index_cond_func_myisam(void *arg)
1303
1376
ha_myisam *h= (ha_myisam*)arg;
1304
1377
/*if (h->in_range_read)*/
1339
int ha_myisam::index_read_map(unsigned char *buf, const unsigned char *key,
1410
int ha_myisam::index_read_map(uchar *buf, const uchar *key,
1340
1411
key_part_map keypart_map,
1341
1412
enum ha_rkey_function find_flag)
1343
assert(inited==INDEX);
1414
DBUG_ASSERT(inited==INDEX);
1344
1415
ha_statistic_increment(&SSV::ha_read_key_count);
1345
1416
int error=mi_rkey(file, buf, active_index, key, keypart_map, find_flag);
1346
1417
table->status=error ? STATUS_NOT_FOUND: 0;
1350
int ha_myisam::index_read_idx_map(unsigned char *buf, uint32_t index, const unsigned char *key,
1421
int ha_myisam::index_read_idx_map(uchar *buf, uint index, const uchar *key,
1351
1422
key_part_map keypart_map,
1352
1423
enum ha_rkey_function find_flag)
1360
int ha_myisam::index_read_last_map(unsigned char *buf, const unsigned char *key,
1431
int ha_myisam::index_read_last_map(uchar *buf, const uchar *key,
1361
1432
key_part_map keypart_map)
1363
assert(inited==INDEX);
1434
DBUG_ENTER("ha_myisam::index_read_last");
1435
DBUG_ASSERT(inited==INDEX);
1364
1436
ha_statistic_increment(&SSV::ha_read_key_count);
1365
1437
int error=mi_rkey(file, buf, active_index, key, keypart_map,
1366
1438
HA_READ_PREFIX_LAST);
1367
1439
table->status=error ? STATUS_NOT_FOUND: 0;
1371
int ha_myisam::index_next(unsigned char *buf)
1443
int ha_myisam::index_next(uchar *buf)
1373
assert(inited==INDEX);
1445
DBUG_ASSERT(inited==INDEX);
1374
1446
ha_statistic_increment(&SSV::ha_read_next_count);
1375
1447
int error=mi_rnext(file,buf,active_index);
1376
1448
table->status=error ? STATUS_NOT_FOUND: 0;
1380
int ha_myisam::index_prev(unsigned char *buf)
1452
int ha_myisam::index_prev(uchar *buf)
1382
assert(inited==INDEX);
1454
DBUG_ASSERT(inited==INDEX);
1383
1455
ha_statistic_increment(&SSV::ha_read_prev_count);
1384
1456
int error=mi_rprev(file,buf, active_index);
1385
1457
table->status=error ? STATUS_NOT_FOUND: 0;
1389
int ha_myisam::index_first(unsigned char *buf)
1461
int ha_myisam::index_first(uchar *buf)
1391
assert(inited==INDEX);
1463
DBUG_ASSERT(inited==INDEX);
1392
1464
ha_statistic_increment(&SSV::ha_read_first_count);
1393
1465
int error=mi_rfirst(file, buf, active_index);
1394
1466
table->status=error ? STATUS_NOT_FOUND: 0;
1398
int ha_myisam::index_last(unsigned char *buf)
1470
int ha_myisam::index_last(uchar *buf)
1400
assert(inited==INDEX);
1472
DBUG_ASSERT(inited==INDEX);
1401
1473
ha_statistic_increment(&SSV::ha_read_last_count);
1402
1474
int error=mi_rlast(file, buf, active_index);
1403
1475
table->status=error ? STATUS_NOT_FOUND: 0;
1407
int ha_myisam::index_next_same(unsigned char *buf,
1408
const unsigned char *key __attribute__((unused)),
1409
uint32_t length __attribute__((unused)))
1479
int ha_myisam::index_next_same(uchar *buf,
1480
const uchar *key __attribute__((unused)),
1481
uint length __attribute__((unused)))
1412
assert(inited==INDEX);
1484
DBUG_ASSERT(inited==INDEX);
1413
1485
ha_statistic_increment(&SSV::ha_read_next_count);
1613
int ha_myisam::create(const char *name, register Table *table_arg,
1689
int ha_myisam::create(const char *name, register TABLE *table_arg,
1614
1690
HA_CREATE_INFO *ha_create_info)
1617
uint32_t create_flags= 0, records;
1693
uint create_flags= 0, records, i;
1618
1694
char buff[FN_REFLEN];
1619
1695
MI_KEYDEF *keydef;
1620
1696
MI_COLUMNDEF *recinfo;
1621
1697
MI_CREATE_INFO create_info;
1622
1698
TABLE_SHARE *share= table_arg->s;
1623
uint32_t options= share->db_options_in_use;
1699
uint options= share->db_options_in_use;
1700
DBUG_ENTER("ha_myisam::create");
1701
for (i= 0; i < share->keys; i++)
1703
if (table_arg->key_info[i].flags & HA_USES_PARSER)
1705
create_flags|= HA_CREATE_RELIES_ON_SQL_LAYER;
1624
1709
if ((error= table2myisam(table_arg, &keydef, &recinfo, &records)))
1625
return(error); /* purecov: inspected */
1626
memset(&create_info, 0, sizeof(create_info));
1710
DBUG_RETURN(error); /* purecov: inspected */
1711
bzero((char*) &create_info, sizeof(create_info));
1627
1712
create_info.max_rows= share->max_rows;
1628
1713
create_info.reloc_rows= share->min_rows;
1629
1714
create_info.with_auto_increment= share->next_number_key_offset == 0;
1668
void ha_myisam::get_auto_increment(uint64_t offset __attribute__((unused)),
1669
uint64_t increment __attribute__((unused)),
1670
uint64_t nb_desired_values __attribute__((unused)),
1753
void ha_myisam::get_auto_increment(uint64_t offset __attribute__((__unused__)),
1754
uint64_t increment __attribute__((__unused__)),
1755
uint64_t nb_desired_values __attribute__((__unused__)),
1671
1756
uint64_t *first_value,
1672
1757
uint64_t *nb_reserved_values)
1676
unsigned char key[MI_MAX_KEY_LENGTH];
1761
uchar key[MI_MAX_KEY_LENGTH];
1678
1763
if (!table->s->next_number_key_offset)
1679
1764
{ // Autoincrement at key-start
1742
ha_rows ha_myisam::records_in_range(uint32_t inx, key_range *min_key,
1827
ha_rows ha_myisam::records_in_range(uint inx, key_range *min_key,
1743
1828
key_range *max_key)
1745
1830
return (ha_rows) mi_records_in_range(file, (int) inx, min_key, max_key);
1749
uint32_t ha_myisam::checksum() const
1834
uint ha_myisam::checksum() const
1751
1836
return (uint)file->state->checksum;
1755
1840
bool ha_myisam::check_if_incompatible_data(HA_CREATE_INFO *info,
1756
uint32_t table_changes)
1758
uint32_t options= table->s->db_options_in_use;
1843
uint options= table->s->db_options_in_use;
1760
1845
if (info->auto_increment_value != stats.auto_increment_value ||
1761
1846
info->data_file_name != data_file_name ||
1807
1894
return ds_mrr.dsmrr_next(this, range_info);
1810
ha_rows ha_myisam::multi_range_read_info_const(uint32_t keyno, RANGE_SEQ_IF *seq,
1897
ha_rows ha_myisam::multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq,
1811
1898
void *seq_init_param,
1812
uint32_t n_ranges, uint32_t *bufsz,
1813
uint32_t *flags, COST_VECT *cost)
1899
uint n_ranges, uint *bufsz,
1900
uint *flags, COST_VECT *cost)
1816
1903
This call is here because there is no location where this->table would
1825
int ha_myisam::multi_range_read_info(uint32_t keyno, uint32_t n_ranges, uint32_t keys,
1826
uint32_t *bufsz, uint32_t *flags, COST_VECT *cost)
1912
int ha_myisam::multi_range_read_info(uint keyno, uint n_ranges, uint keys,
1913
uint *bufsz, uint *flags, COST_VECT *cost)
1828
1915
ds_mrr.init(this, table);
1829
1916
return ds_mrr.dsmrr_info(keyno, n_ranges, keys, bufsz, flags, cost);
1936
struct st_mysql_storage_engine myisam_storage_engine=
1937
{ MYSQL_HANDLERTON_INTERFACE_VERSION };
1849
1939
mysql_declare_plugin(myisam)
1851
DRIZZLE_STORAGE_ENGINE_PLUGIN,
1941
MYSQL_STORAGE_ENGINE_PLUGIN,
1942
&myisam_storage_engine,
1855
1945
"Default engine as of MySQL 3.23 with great performance",
1856
1946
PLUGIN_LICENSE_GPL,
1857
1947
myisam_init, /* Plugin Init */
1858
myisam_deinit, /* Plugin Deinit */
1948
NULL, /* Plugin Deinit */
1859
1950
NULL, /* status variables */
1860
1951
NULL, /* system variables */
1861
1952
NULL /* config options */
1863
1954
mysql_declare_plugin_end;
1957
#ifdef HAVE_QUERY_CACHE
1959
@brief Register a named table with a call back function to the query cache.
1961
@param thd The thread handle
1962
@param table_key A pointer to the table name in the table cache
1963
@param key_length The length of the table name
1964
@param[out] engine_callback The pointer to the storage engine call back
1965
function, currently 0
1966
@param[out] engine_data Engine data will be set to 0.
1968
@note Despite the name of this function, it is used to check each statement
1969
before it is cached and not to register a table or callback function.
1971
@see handler::register_query_cache_table
1973
@return The error code. The engine_data and engine_callback will be set to 0.
1974
@retval true Success
1975
@retval false An error occured
1978
my_bool ha_myisam::register_query_cache_table(THD *thd, char *table_name,
1979
uint table_name_len,
1982
uint64_t *engine_data)
1984
DBUG_ENTER("ha_myisam::register_query_cache_table");
1986
No call back function is needed to determine if a cached statement
1989
*engine_callback= 0;
1992
No engine data is needed.
1996
if (file->s->concurrent_insert)
1999
If a concurrent INSERT has happened just before the currently
2000
processed SELECT statement, the total size of the table is
2003
To determine if the table size is known, the current thread's snap
2004
shot of the table size with the actual table size are compared.
2006
If the table size is unknown the SELECT statement can't be cached.
2008
When concurrent inserts are disabled at table open, mi_open()
2009
does not assign a get_status() function. In this case the local
2010
("current") status is never updated. We would wrongly think that
2011
we cannot cache the statement.
2013
uint64_t actual_data_file_length;
2014
uint64_t current_data_file_length;
2017
POSIX visibility rules specify that "2. Whatever memory values a
2018
thread can see when it unlocks a mutex <...> can also be seen by any
2019
thread that later locks the same mutex". In this particular case,
2020
concurrent insert thread had modified the data_file_length in
2021
MYISAM_SHARE before it has unlocked (or even locked)
2022
structure_guard_mutex. So, here we're guaranteed to see at least that
2023
value after we've locked the same mutex. We can see a later value
2024
(modified by some other thread) though, but it's ok, as we only want
2025
to know if the variable was changed, the actual new value doesn't matter
2027
actual_data_file_length= file->s->state.state.data_file_length;
2028
current_data_file_length= file->save_state.data_file_length;
2030
if (current_data_file_length != actual_data_file_length)
2032
/* Don't cache current statement. */
2037
/* It is ok to try to cache current statement. */