20 #include <my_getopt.h>
23 #define MAX_REC_LENGTH 1024
27 static int rec_pointer_size=0,
flags[50];
28 static int key_field=FIELD_SKIP_PRESPACE,extra_field=FIELD_SKIP_ENDSPACE;
29 static int key_type=HA_KEYTYPE_NUM;
30 static int create_flag=0;
32 static uint insert_count, update_count, remove_count;
33 static uint pack_keys=0, pack_seg=0, key_length;
34 static uint unique_key=HA_NOSAME;
35 static my_bool key_cacheing, null_fields, silent, skip_update, opt_unique,
42 static int run_test(
const char *filename);
43 static void get_options(
int argc,
char *argv[]);
44 static void create_key(uchar *key,uint rownr);
45 static void create_record(uchar *
record,uint rownr);
46 static void update_record(uchar *
record);
48 int main(
int argc,
char *argv[])
53 init_key_cache(dflt_key_cache,KEY_CACHE_BLOCK_SIZE,IO_SIZE*16,0,0);
54 get_options(argc,argv);
56 exit(run_test(
"test1"));
60 static int run_test(
const char *filename)
63 int i,j,error,deleted,rec_length,uniques=0;
64 ha_rows found,row_count;
66 uchar
record[MAX_REC_LENGTH],key[MAX_REC_LENGTH],read_record[MAX_REC_LENGTH];
70 memset(recinfo, 0,
sizeof(recinfo));
73 recinfo[0].type=FIELD_NORMAL; recinfo[0].length=1;
74 recinfo[1].type=key_field;
75 recinfo[1].length= (key_field == FIELD_BLOB ? 4+portable_sizeof_char_ptr :
77 if (key_field == FIELD_VARCHAR)
78 recinfo[1].length+= HA_VARCHAR_PACKLENGTH(key_length);;
79 recinfo[2].type=extra_field;
80 recinfo[2].length= (extra_field == FIELD_BLOB ? 4 + portable_sizeof_char_ptr : 24);
81 if (extra_field == FIELD_VARCHAR)
82 recinfo[2].length+= HA_VARCHAR_PACKLENGTH(recinfo[2].length);
85 recinfo[3].type=FIELD_CHECK;
86 recinfo[3].length=MI_UNIQUE_HASH_LENGTH;
88 rec_length=recinfo[0].length+recinfo[1].length+recinfo[2].length+
91 if (key_type == HA_KEYTYPE_VARTEXT1 &&
93 key_type= HA_KEYTYPE_VARTEXT2;
96 keyinfo[0].seg=keyseg;
98 keyinfo[0].block_length= 0;
99 keyinfo[0].key_alg=HA_KEY_ALG_BTREE;
100 keyinfo[0].seg[0].type= key_type;
101 keyinfo[0].seg[0].flag= pack_seg;
102 keyinfo[0].seg[0].start=1;
103 keyinfo[0].seg[0].length=key_length;
104 keyinfo[0].seg[0].null_bit= null_fields ? 2 : 0;
105 keyinfo[0].seg[0].null_pos=0;
106 keyinfo[0].seg[0].language= default_charset_info->number;
107 if (pack_seg & HA_BLOB_PART)
109 keyinfo[0].seg[0].bit_start=4;
111 keyinfo[0].flag = (uint8) (pack_keys | unique_key);
118 memset(&uniquedef, 0,
sizeof(uniquedef));
119 memset(uniqueseg, 0,
sizeof(uniqueseg));
120 uniquedef.seg=uniqueseg;
124 for (i=0, start=1 ; i < 2 ; i++)
126 uniqueseg[
i].start=start;
127 start+=recinfo[i+1].length;
128 uniqueseg[
i].length=recinfo[i+1].length;
129 uniqueseg[
i].language= default_charset_info->number;
131 uniqueseg[0].type= key_type;
132 uniqueseg[0].null_bit= null_fields ? 2 : 0;
133 uniqueseg[1].type= HA_KEYTYPE_TEXT;
134 if (extra_field == FIELD_BLOB)
136 uniqueseg[1].length=0;
137 uniqueseg[1].bit_start=4;
138 uniqueseg[1].flag|= HA_BLOB_PART;
140 else if (extra_field == FIELD_VARCHAR)
141 uniqueseg[1].flag|= HA_VAR_LENGTH_PART;
147 printf(
"- Creating isam-file\n");
148 memset(&create_info, 0,
sizeof(create_info));
149 create_info.max_rows=(ulong) (rec_pointer_size ?
150 (1L << (rec_pointer_size*8))/40 :
152 if (mi_create(filename,1,keyinfo,3+opt_unique,recinfo,
153 uniques, &uniquedef, &create_info,
156 if (!(file=mi_open(filename,2,HA_OPEN_ABORT_IF_LOCKED)))
159 printf(
"- Writing key:s\n");
163 for (i=49 ; i>=1 ; i-=2 )
165 if (insert_count-- == 0) { (void) mi_close(file); exit(0) ; }
167 create_record(record,j);
168 error=mi_write(file,record);
172 if (verbose || error)
173 printf(
"J= %2d mi_write: %d errno: %d\n", j,error,my_errno);
179 create_record(record,0);
180 error=mi_write(file,record);
183 if (verbose || error)
184 printf(
"J= NULL mi_write: %d errno: %d\n", error,my_errno);
185 error=mi_write(file,record);
188 if (verbose || error)
189 printf(
"J= NULL mi_write: %d errno: %d\n", error,my_errno);
198 printf(
"- Checking unique constraint\n");
199 create_record(record,j);
200 if (!mi_write(file,record) || my_errno != HA_ERR_FOUND_DUPP_UNIQUE)
202 printf(
"unique check failed\n");
206 printf(
"- Updating rows\n");
209 if (mi_rsame(file,read_record,-1))
211 printf(
"Can't find last row with mi_rsame\n");
215 memcpy(record,read_record,rec_length);
216 update_record(record);
217 if (mi_update(file,read_record,record))
219 printf(
"Can't update last row: %.*s\n",
220 keyinfo[0].seg[0].length,read_record+1);
227 while ((error=mi_rrnd(file,read_record,pos)) == 0)
229 if (update_count-- == 0) { (void) mi_close(file); exit(0) ; }
230 memcpy(record,read_record,rec_length);
231 update_record(record);
232 if (mi_update(file,read_record,record))
234 printf(
"Can't update row: %.*s, error: %d\n",
235 keyinfo[0].seg[0].length,record+1,my_errno);
240 if (found != row_count)
241 printf(
"Found %ld of %ld rows\n", (ulong) found, (ulong) row_count);
245 printf(
"- Reopening file\n");
246 if (mi_close(file))
goto err;
247 if (!(file=mi_open(filename,2,HA_OPEN_ABORT_IF_LOCKED)))
goto err;
251 printf(
"- Removing keys\n");
253 for (i=0 ; i <= 10 ; i++)
256 if (remove_count-- == 0) { (void) mi_close(file); exit(0) ; }
262 if ((error = mi_rkey(file,read_record,0,key,HA_WHOLE_KEY,
265 if (verbose || (
flags[j] >= 1 ||
266 (error && my_errno != HA_ERR_KEY_NOT_FOUND)))
267 printf(
"key: '%.*s' mi_rkey: %3d errno: %3d\n",
268 (
int) key_length,key+
test(null_fields),error,my_errno);
272 error=mi_delete(file,read_record);
273 if (verbose || error)
274 printf(
"key: '%.*s' mi_delete: %3d errno: %3d\n",
275 (
int) key_length, key+
test(null_fields), error, my_errno);
285 printf(
"- Reading rows with key\n");
286 for (i=0 ; i <= 25 ; i++)
290 error=mi_rkey(file,read_record,0,key,HA_WHOLE_KEY,HA_READ_KEY_EXACT);
292 (error == 0 &&
flags[i] == 0 && unique_key) ||
293 (error && (
flags[i] != 0 || my_errno != HA_ERR_KEY_NOT_FOUND)))
295 printf(
"key: '%.*s' mi_rkey: %3d errno: %3d record: %s\n",
296 (
int) key_length,key+
test(null_fields),error,my_errno,record+1);
301 printf(
"- Reading rows with position\n");
302 for (i=1,found=0 ; i <= 30 ; i++)
305 if ((error=mi_rrnd(file,read_record,i == 1 ? 0L : HA_OFFSET_ERROR)) == -1)
307 if (found != row_count-deleted)
308 printf(
"Found only %ld of %ld rows\n", (ulong) found,
309 (ulong) (row_count - deleted));
314 if (verbose || (error != 0 && error != HA_ERR_RECORD_DELETED &&
315 error != HA_ERR_END_OF_FILE))
317 printf(
"pos: %2d mi_rrnd: %3d errno: %3d record: %s\n",
318 i-1,error,my_errno,read_record+1);
321 if (mi_close(file))
goto err;
322 my_end(MY_CHECK_ERROR);
326 printf(
"got error: %3d when using myisam-database\n",my_errno);
331 static void create_key_part(uchar *key,uint rownr)
335 if (keyinfo[0].seg[0].
type == HA_KEYTYPE_NUM)
337 sprintf((
char*) key,
"%*d",keyinfo[0].seg[0].length,rownr);
339 else if (keyinfo[0].seg[0].
type == HA_KEYTYPE_VARTEXT1 ||
340 keyinfo[0].seg[0].
type == HA_KEYTYPE_VARTEXT2)
343 memset(key, rownr < 10 ?
'A' :
'B', keyinfo[0].seg[0].length);
344 sprintf((
char*) key+keyinfo[0].seg[0].length-2,
"%-2d",rownr);
345 if ((rownr & 7) == 0)
348 memset(key + 3, rownr < 10 ?
'a' :
'b', keyinfo[0].seg[0].length-4);
353 if (keyinfo[0].seg[0].flag & HA_SPACE_PACK)
354 sprintf((
char*) key,
"%-*d",keyinfo[0].seg[0].length,rownr);
358 memset(key, rownr < 10 ?
'A' :
'B', keyinfo[0].seg[0].length);
359 sprintf((
char*) key+keyinfo[0].seg[0].length-2,
"%-2d",rownr);
360 if ((rownr & 7) == 0)
363 key[1]= (rownr < 10 ?
'a' :
'b');
370 static void create_key(uchar *key,uint rownr)
372 if (keyinfo[0].seg[0].null_bit)
382 if (keyinfo[0].seg[0].flag & (HA_BLOB_PART | HA_VAR_LENGTH_PART))
385 create_key_part(key+2,rownr);
386 tmp=strlen((
char*) key+2);
390 create_key_part(key,rownr);
394 static uchar blob_key[MAX_REC_LENGTH];
395 static uchar blob_record[MAX_REC_LENGTH+20*20];
398 static void create_record(uchar *record,uint rownr)
401 memset(record, 0, MAX_REC_LENGTH);
403 if (rownr == 0 && keyinfo[0].seg[0].null_bit)
404 record[0]|=keyinfo[0].seg[0].null_bit;
407 if (recinfo[1].
type == FIELD_BLOB)
411 create_key_part(blob_key,rownr);
412 tmp=strlen((
char*) blob_key);
415 memcpy(pos+4, &ptr,
sizeof(
char*));
416 pos+=recinfo[1].length;
418 else if (recinfo[1].
type == FIELD_VARCHAR)
420 uint tmp, pack_length= HA_VARCHAR_PACKLENGTH(recinfo[1].length-1);
421 create_key_part(pos+pack_length,rownr);
422 tmp= strlen((
char*) pos+pack_length);
423 if (pack_length == 1)
424 *(uchar*) pos= (uchar) tmp;
427 pos+= recinfo[1].length;
431 create_key_part(pos,rownr);
432 pos+=recinfo[1].length;
434 if (recinfo[2].
type == FIELD_BLOB)
438 sprintf((
char*) blob_record,
"... row: %d", rownr);
439 strappend((
char*) blob_record,max(MAX_REC_LENGTH-rownr,10),
' ');
440 tmp=strlen((
char*) blob_record);
443 memcpy(pos+4, &ptr,
sizeof(
char*));
445 else if (recinfo[2].
type == FIELD_VARCHAR)
447 uint tmp, pack_length= HA_VARCHAR_PACKLENGTH(recinfo[1].length-1);
448 sprintf((
char*) pos+pack_length,
"... row: %d", rownr);
449 tmp= strlen((
char*) pos+pack_length);
450 if (pack_length == 1)
457 sprintf((
char*) pos,
"... row: %d", rownr);
458 strappend((
char*) pos,recinfo[2].length,
' ');
464 static void update_record(uchar *record)
467 if (recinfo[1].
type == FIELD_BLOB)
471 length=uint4korr(pos);
472 memcpy(&column, pos+4,
sizeof(
char*));
473 memcpy(blob_key,column,length);
475 memcpy(pos+4, &ptr,
sizeof(
char*));
476 if (keyinfo[0].seg[0].
type != HA_KEYTYPE_NUM)
477 default_charset_info->cset->casedn(default_charset_info,
478 (
char*) blob_key, length,
479 (
char*) blob_key, length);
480 pos+=recinfo[1].length;
482 else if (recinfo[1].
type == FIELD_VARCHAR)
484 uint pack_length= HA_VARCHAR_PACKLENGTH(recinfo[1].length-1);
485 uint length= pack_length == 1 ? (uint) *(uchar*) pos : uint2korr(pos);
486 default_charset_info->cset->casedn(default_charset_info,
487 (
char*) pos + pack_length, length,
488 (
char*) pos + pack_length, length);
489 pos+=recinfo[1].length;
493 if (keyinfo[0].seg[0].
type != HA_KEYTYPE_NUM)
494 default_charset_info->cset->casedn(default_charset_info,
495 (
char*) pos, keyinfo[0].seg[0].length,
496 (
char*) pos, keyinfo[0].seg[0].length);
497 pos+=recinfo[1].length;
500 if (recinfo[2].
type == FIELD_BLOB)
504 length=uint4korr(pos);
505 memcpy(&column, pos+4,
sizeof(
char*));
506 memcpy(blob_record,column,length);
507 memset(blob_record + length,
'.', 20);
509 int4store(pos,length);
511 memcpy(pos+4, &column,
sizeof(
char*));
513 else if (recinfo[2].
type == FIELD_VARCHAR)
516 uint pack_length= HA_VARCHAR_PACKLENGTH(recinfo[1].length-1);
517 uint length= pack_length == 1 ? (uint) *(uchar*) pos : uint2korr(pos);
518 memset(pos + pack_length + length,
'.',
519 recinfo[2].length - length-pack_length);
520 length=recinfo[2].length-pack_length;
521 if (pack_length == 1)
522 *(uchar*) pos= (uchar) length;
524 int2store(pos,length);
528 memset(pos + recinfo[2].length - 10,
'.', 10);
533 static struct my_option my_long_options[] =
535 {
"checksum",
'c',
"Undocumented",
536 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
538 {
"debug",
'#',
"Undocumented",
539 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
541 {
"delete_rows",
'd',
"Undocumented", &remove_count,
542 &remove_count, 0, GET_UINT, REQUIRED_ARG, 1000, 0, 0, 0, 0, 0},
543 {
"help",
'?',
"Display help and exit",
544 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
545 {
"insert_rows",
'i',
"Undocumented", &insert_count,
546 &insert_count, 0, GET_UINT, REQUIRED_ARG, 1000, 0, 0, 0, 0, 0},
547 {
"key_alpha",
'a',
"Use a key of type HA_KEYTYPE_TEXT",
548 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
549 {
"key_binary_pack",
'B',
"Undocumented",
550 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
551 {
"key_blob",
'b',
"Undocumented",
552 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
553 {
"key_cache",
'K',
"Undocumented", &key_cacheing,
554 &key_cacheing, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
555 {
"key_length",
'k',
"Undocumented", &key_length, &key_length,
556 0, GET_UINT, REQUIRED_ARG, 6, 0, 0, 0, 0, 0},
557 {
"key_multiple",
'm',
"Undocumented",
558 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
559 {
"key_prefix_pack",
'P',
"Undocumented",
560 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
561 {
"key_space_pack",
'p',
"Undocumented",
562 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
563 {
"key_varchar",
'w',
"Test VARCHAR keys",
564 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
565 {
"null_fields",
'N',
"Define fields with NULL",
566 &null_fields, &null_fields, 0, GET_BOOL, NO_ARG,
568 {
"row_fixed_size",
'S',
"Undocumented",
569 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
570 {
"row_pointer_size",
'R',
"Undocumented", &rec_pointer_size,
571 &rec_pointer_size, 0, GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
572 {
"silent",
's',
"Undocumented",
573 &silent, &silent, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
574 {
"skip_update",
'U',
"Undocumented", &skip_update,
575 &skip_update, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
576 {
"unique",
'C',
"Undocumented", &opt_unique, &opt_unique, 0,
577 GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
578 {
"update_rows",
'u',
"Undocumented", &update_count,
579 &update_count, 0, GET_UINT, REQUIRED_ARG, 1000, 0, 0, 0, 0, 0},
580 {
"verbose",
'v',
"Be more verbose", &verbose, &verbose, 0,
581 GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
582 {
"version",
'V',
"Print version number and exit",
583 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
584 { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
589 get_one_option(
int optid,
const struct my_option *opt __attribute__((unused)),
590 char *argument __attribute__((unused)))
594 key_type= HA_KEYTYPE_TEXT;
597 create_flag|= HA_CREATE_CHECKSUM;
600 if (rec_pointer_size > 3)
604 pack_keys= HA_PACK_KEY;
607 pack_keys= HA_BINARY_PACK_KEY;
610 if (key_field == FIELD_VARCHAR)
614 else if (key_field != FIELD_BLOB)
616 key_field=FIELD_NORMAL;
617 extra_field=FIELD_NORMAL;
621 pack_keys=HA_PACK_KEY;
622 pack_seg=HA_SPACE_PACK;
623 key_type=HA_KEYTYPE_TEXT;
629 key_field=FIELD_BLOB;
630 extra_field= FIELD_BLOB;
631 pack_seg|= HA_BLOB_PART;
632 key_type= HA_KEYTYPE_VARTEXT1;
635 if (key_length < 4 || key_length > MI_MAX_KEY_LENGTH)
637 fprintf(stderr,
"Wrong key length\n");
642 key_field=FIELD_VARCHAR;
643 extra_field= FIELD_VARCHAR;
644 key_type= HA_KEYTYPE_VARTEXT1;
645 pack_seg|= HA_VAR_LENGTH_PART;
646 create_flag|= HA_PACK_RECORD;
652 printf(
"test1 Ver 1.2 \n");
655 DBUG_PUSH (argument);
667 static void get_options(
int argc,
char *argv[])
671 if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option)))
680 printf(
"Usage: %s [options]\n\n", my_progname);
681 my_print_help(my_long_options);
682 my_print_variables(my_long_options);
685 #include "mi_extrafunc.h"