1 | /* |
2 | Copyright (c) 2000, 2011, Oracle and/or its affiliates |
3 | |
4 | This program is free software; you can redistribute it and/or modify |
5 | it under the terms of the GNU General Public License as published by |
6 | the Free Software Foundation; version 2 of the License. |
7 | |
8 | This program is distributed in the hope that it will be useful, |
9 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
11 | GNU General Public License for more details. |
12 | |
13 | You should have received a copy of the GNU General Public License |
14 | along with this program; if not, write to the Free Software |
15 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ |
16 | |
17 | /* Testing of the basic functions of a MyISAM table */ |
18 | |
19 | #include <my_global.h> |
20 | #include "myisam.h" |
21 | #include <my_getopt.h> |
22 | #include <m_string.h> |
23 | |
24 | #define MAX_REC_LENGTH 1024 |
25 | |
26 | static void usage(); |
27 | |
28 | static int rec_pointer_size=0, flags[50]; |
29 | static int key_field=FIELD_SKIP_PRESPACE,=FIELD_SKIP_ENDSPACE; |
30 | static int key_type=HA_KEYTYPE_NUM; |
31 | static int create_flag=0; |
32 | |
33 | static uint insert_count, update_count, remove_count; |
34 | static uint pack_keys=0, pack_seg=0, key_length; |
35 | static uint unique_key=HA_NOSAME; |
36 | static my_bool key_cacheing, null_fields, silent, skip_update, opt_unique, |
37 | verbose; |
38 | static MI_COLUMNDEF recinfo[4]; |
39 | static MI_KEYDEF keyinfo[10]; |
40 | static HA_KEYSEG keyseg[10]; |
41 | static HA_KEYSEG uniqueseg[10]; |
42 | |
43 | static int run_test(const char *filename); |
44 | static void get_options(int argc, char *argv[]); |
45 | static void create_key(uchar *key,uint rownr); |
46 | static void create_record(uchar *record,uint rownr); |
47 | static void update_record(uchar *record); |
48 | |
49 | int main(int argc,char *argv[]) |
50 | { |
51 | MY_INIT(argv[0]); |
52 | my_init(); |
53 | if (key_cacheing) |
54 | init_key_cache(dflt_key_cache,KEY_CACHE_BLOCK_SIZE,IO_SIZE*16,0,0, |
55 | 0, DEFAULT_KEY_CACHE_PARTITIONS); |
56 | get_options(argc,argv); |
57 | |
58 | exit(run_test("test1" )); |
59 | } |
60 | |
61 | |
62 | static int run_test(const char *filename) |
63 | { |
64 | MI_INFO *file; |
65 | int i,j,error,deleted,rec_length,uniques=0; |
66 | ha_rows found,row_count; |
67 | my_off_t pos; |
68 | uchar record[MAX_REC_LENGTH],key[MAX_REC_LENGTH],read_record[MAX_REC_LENGTH]; |
69 | MI_UNIQUEDEF uniquedef; |
70 | MI_CREATE_INFO create_info; |
71 | |
72 | bzero((char*) recinfo,sizeof(recinfo)); |
73 | |
74 | /* First define 2 columns */ |
75 | recinfo[0].type=FIELD_NORMAL; recinfo[0].length=1; /* For NULL bits */ |
76 | recinfo[1].type=key_field; |
77 | recinfo[1].length= (key_field == FIELD_BLOB ? 4+portable_sizeof_char_ptr : |
78 | key_length); |
79 | if (key_field == FIELD_VARCHAR) |
80 | recinfo[1].length+= HA_VARCHAR_PACKLENGTH(key_length);; |
81 | recinfo[2].type=extra_field; |
82 | recinfo[2].length= (extra_field == FIELD_BLOB ? 4 + portable_sizeof_char_ptr : 24); |
83 | if (extra_field == FIELD_VARCHAR) |
84 | recinfo[2].length+= HA_VARCHAR_PACKLENGTH(recinfo[2].length); |
85 | recinfo[1].null_bit= null_fields ? 2 : 0; |
86 | |
87 | if (opt_unique) |
88 | { |
89 | recinfo[3].type=FIELD_CHECK; |
90 | recinfo[3].length=MI_UNIQUE_HASH_LENGTH; |
91 | } |
92 | rec_length=recinfo[0].length+recinfo[1].length+recinfo[2].length+ |
93 | recinfo[3].length; |
94 | |
95 | if (key_type == HA_KEYTYPE_VARTEXT1 && |
96 | key_length > 255) |
97 | key_type= HA_KEYTYPE_VARTEXT2; |
98 | |
99 | /* Define a key over the first column */ |
100 | keyinfo[0].seg=keyseg; |
101 | keyinfo[0].keysegs=1; |
102 | keyinfo[0].block_length= 0; /* Default block length */ |
103 | keyinfo[0].key_alg=HA_KEY_ALG_BTREE; |
104 | keyinfo[0].seg[0].type= key_type; |
105 | keyinfo[0].seg[0].flag= pack_seg; |
106 | keyinfo[0].seg[0].start=1; |
107 | keyinfo[0].seg[0].length=key_length; |
108 | keyinfo[0].seg[0].null_bit= null_fields ? 2 : 0; |
109 | keyinfo[0].seg[0].null_pos=0; |
110 | keyinfo[0].seg[0].language= default_charset_info->number; |
111 | if (pack_seg & HA_BLOB_PART) |
112 | { |
113 | keyinfo[0].seg[0].bit_start=4; /* Length of blob length */ |
114 | } |
115 | keyinfo[0].flag = (uint8) (pack_keys | unique_key); |
116 | |
117 | bzero((uchar*) flags,sizeof(flags)); |
118 | if (opt_unique) |
119 | { |
120 | uint start; |
121 | uniques=1; |
122 | bzero((char*) &uniquedef,sizeof(uniquedef)); |
123 | bzero((char*) uniqueseg,sizeof(uniqueseg)); |
124 | uniquedef.seg=uniqueseg; |
125 | uniquedef.keysegs=2; |
126 | |
127 | /* Make a unique over all columns (except first NULL fields) */ |
128 | for (i=0, start=1 ; i < 2 ; i++) |
129 | { |
130 | uniqueseg[i].start=start; |
131 | start+=recinfo[i+1].length; |
132 | uniqueseg[i].length=recinfo[i+1].length; |
133 | uniqueseg[i].language= default_charset_info->number; |
134 | } |
135 | uniqueseg[0].type= key_type; |
136 | uniqueseg[0].null_bit= null_fields ? 2 : 0; |
137 | uniqueseg[1].type= HA_KEYTYPE_TEXT; |
138 | if (extra_field == FIELD_BLOB) |
139 | { |
140 | uniqueseg[1].length=0; /* The whole blob */ |
141 | uniqueseg[1].bit_start=4; /* long blob */ |
142 | uniqueseg[1].flag|= HA_BLOB_PART; |
143 | } |
144 | else if (extra_field == FIELD_VARCHAR) |
145 | uniqueseg[1].flag|= HA_VAR_LENGTH_PART; |
146 | } |
147 | else |
148 | uniques=0; |
149 | |
150 | if (!silent) |
151 | printf("- Creating isam-file\n" ); |
152 | bzero((char*) &create_info,sizeof(create_info)); |
153 | create_info.max_rows=(ulong) (rec_pointer_size ? |
154 | (1L << (rec_pointer_size*8))/40 : |
155 | 0); |
156 | if (mi_create(filename,1,keyinfo,3+opt_unique,recinfo, |
157 | uniques, &uniquedef, &create_info, |
158 | create_flag)) |
159 | goto err; |
160 | if (!(file=mi_open(filename,2,HA_OPEN_ABORT_IF_LOCKED))) |
161 | goto err; |
162 | if (!silent) |
163 | printf("- Writing key:s\n" ); |
164 | |
165 | my_errno=0; |
166 | row_count=deleted=0; |
167 | for (i=49 ; i>=1 ; i-=2 ) |
168 | { |
169 | if (insert_count-- == 0) { (void) mi_close(file); exit(0) ; } |
170 | j=i%25 +1; |
171 | create_record(record,j); |
172 | error=mi_write(file,record); |
173 | if (!error) |
174 | row_count++; |
175 | flags[j]=1; |
176 | if (verbose || error) |
177 | printf("J= %2d mi_write: %d errno: %d\n" , j,error,my_errno); |
178 | } |
179 | |
180 | /* Insert 2 rows with null values */ |
181 | if (null_fields) |
182 | { |
183 | create_record(record,0); |
184 | error=mi_write(file,record); |
185 | if (!error) |
186 | row_count++; |
187 | if (verbose || error) |
188 | printf("J= NULL mi_write: %d errno: %d\n" , error,my_errno); |
189 | error=mi_write(file,record); |
190 | if (!error) |
191 | row_count++; |
192 | if (verbose || error) |
193 | printf("J= NULL mi_write: %d errno: %d\n" , error,my_errno); |
194 | flags[0]=2; |
195 | } |
196 | |
197 | if (!skip_update) |
198 | { |
199 | if (opt_unique) |
200 | { |
201 | if (!silent) |
202 | printf("- Checking unique constraint\n" ); |
203 | create_record(record,j); |
204 | if (!mi_write(file,record) || my_errno != HA_ERR_FOUND_DUPP_UNIQUE) |
205 | { |
206 | printf("unique check failed\n" ); |
207 | } |
208 | } |
209 | if (!silent) |
210 | printf("- Updating rows\n" ); |
211 | |
212 | /* Update first last row to force extend of file */ |
213 | if (mi_rsame(file,read_record,-1)) |
214 | { |
215 | printf("Can't find last row with mi_rsame\n" ); |
216 | } |
217 | else |
218 | { |
219 | memcpy(record,read_record,rec_length); |
220 | update_record(record); |
221 | if (mi_update(file,read_record,record)) |
222 | { |
223 | printf("Can't update last row: %.*s\n" , |
224 | keyinfo[0].seg[0].length,read_record+1); |
225 | } |
226 | } |
227 | |
228 | /* Read through all rows and update them */ |
229 | pos=(my_off_t) 0; |
230 | found=0; |
231 | while ((error=mi_rrnd(file,read_record,pos)) == 0) |
232 | { |
233 | if (update_count-- == 0) { (void) mi_close(file); exit(0) ; } |
234 | memcpy(record,read_record,rec_length); |
235 | update_record(record); |
236 | if (mi_update(file,read_record,record)) |
237 | { |
238 | printf("Can't update row: %.*s, error: %d\n" , |
239 | keyinfo[0].seg[0].length,record+1,my_errno); |
240 | } |
241 | found++; |
242 | pos=HA_OFFSET_ERROR; |
243 | } |
244 | if (found != row_count) |
245 | printf("Found %ld of %ld rows\n" , (ulong) found, (ulong) row_count); |
246 | } |
247 | |
248 | if (!silent) |
249 | printf("- Reopening file\n" ); |
250 | if (mi_close(file)) goto err; |
251 | if (!(file=mi_open(filename,2,HA_OPEN_ABORT_IF_LOCKED))) goto err; |
252 | if (!skip_update) |
253 | { |
254 | if (!silent) |
255 | printf("- Removing keys\n" ); |
256 | |
257 | for (i=0 ; i <= 10 ; i++) |
258 | { |
259 | /* testing */ |
260 | if (remove_count-- == 0) { (void) mi_close(file); exit(0) ; } |
261 | j=i*2; |
262 | if (!flags[j]) |
263 | continue; |
264 | create_key(key,j); |
265 | my_errno=0; |
266 | if ((error = mi_rkey(file,read_record,0,key,HA_WHOLE_KEY, |
267 | HA_READ_KEY_EXACT))) |
268 | { |
269 | if (verbose || (flags[j] >= 1 || |
270 | (error && my_errno != HA_ERR_KEY_NOT_FOUND))) |
271 | printf("key: '%.*s' mi_rkey: %3d errno: %3d\n" , |
272 | (int) key_length, key + MY_TEST(null_fields), error, my_errno); |
273 | } |
274 | else |
275 | { |
276 | error=mi_delete(file,read_record); |
277 | if (verbose || error) |
278 | printf("key: '%.*s' mi_delete: %3d errno: %3d\n" , |
279 | (int) key_length, key + MY_TEST(null_fields), error, my_errno); |
280 | if (! error) |
281 | { |
282 | deleted++; |
283 | flags[j]--; |
284 | } |
285 | } |
286 | } |
287 | } |
288 | if (!silent) |
289 | printf("- Reading rows with key\n" ); |
290 | for (i=0 ; i <= 25 ; i++) |
291 | { |
292 | create_key(key,i); |
293 | my_errno=0; |
294 | error=mi_rkey(file,read_record,0,key,HA_WHOLE_KEY,HA_READ_KEY_EXACT); |
295 | if (verbose || |
296 | (error == 0 && flags[i] == 0 && unique_key) || |
297 | (error && (flags[i] != 0 || my_errno != HA_ERR_KEY_NOT_FOUND))) |
298 | { |
299 | printf("key: '%.*s' mi_rkey: %3d errno: %3d record: %s\n" , |
300 | (int) key_length, key + MY_TEST(null_fields), error, my_errno, |
301 | record + 1); |
302 | } |
303 | } |
304 | |
305 | if (!silent) |
306 | printf("- Reading rows with position\n" ); |
307 | for (i=1,found=0 ; i <= 30 ; i++) |
308 | { |
309 | my_errno=0; |
310 | if ((error=mi_rrnd(file,read_record,i == 1 ? 0L : HA_OFFSET_ERROR)) == -1) |
311 | { |
312 | if (found != row_count-deleted) |
313 | printf("Found only %ld of %ld rows\n" , (ulong) found, |
314 | (ulong) (row_count - deleted)); |
315 | break; |
316 | } |
317 | if (!error) |
318 | found++; |
319 | if (verbose || (error != 0 && error != HA_ERR_RECORD_DELETED && |
320 | error != HA_ERR_END_OF_FILE)) |
321 | { |
322 | printf("pos: %2d mi_rrnd: %3d errno: %3d record: %s\n" , |
323 | i-1,error,my_errno,read_record+1); |
324 | } |
325 | } |
326 | if (mi_close(file)) goto err; |
327 | my_end(MY_CHECK_ERROR); |
328 | |
329 | return (0); |
330 | err: |
331 | printf("got error: %3d when using myisam-database\n" ,my_errno); |
332 | return 1; /* skip warning */ |
333 | } |
334 | |
335 | |
336 | static void create_key_part(uchar *key,uint rownr) |
337 | { |
338 | if (!unique_key) |
339 | rownr&=7; /* Some identical keys */ |
340 | if (keyinfo[0].seg[0].type == HA_KEYTYPE_NUM) |
341 | { |
342 | sprintf((char*) key,"%*d" ,keyinfo[0].seg[0].length,rownr); |
343 | } |
344 | else if (keyinfo[0].seg[0].type == HA_KEYTYPE_VARTEXT1 || |
345 | keyinfo[0].seg[0].type == HA_KEYTYPE_VARTEXT2) |
346 | { /* Alpha record */ |
347 | /* Create a key that may be easily packed */ |
348 | bfill(key,keyinfo[0].seg[0].length,rownr < 10 ? 'A' : 'B'); |
349 | sprintf((char*) key+keyinfo[0].seg[0].length-2,"%-2d" ,rownr); |
350 | if ((rownr & 7) == 0) |
351 | { |
352 | /* Change the key to force a unpack of the next key */ |
353 | bfill(key+3,keyinfo[0].seg[0].length-4,rownr < 10 ? 'a' : 'b'); |
354 | } |
355 | } |
356 | else |
357 | { /* Alpha record */ |
358 | if (keyinfo[0].seg[0].flag & HA_SPACE_PACK) |
359 | sprintf((char*) key,"%-*d" ,keyinfo[0].seg[0].length,rownr); |
360 | else |
361 | { |
362 | /* Create a key that may be easily packed */ |
363 | bfill(key,keyinfo[0].seg[0].length,rownr < 10 ? 'A' : 'B'); |
364 | sprintf((char*) key+keyinfo[0].seg[0].length-2,"%-2d" ,rownr); |
365 | if ((rownr & 7) == 0) |
366 | { |
367 | /* Change the key to force a unpack of the next key */ |
368 | key[1]= (rownr < 10 ? 'a' : 'b'); |
369 | } |
370 | } |
371 | } |
372 | } |
373 | |
374 | |
375 | static void create_key(uchar *key,uint rownr) |
376 | { |
377 | if (keyinfo[0].seg[0].null_bit) |
378 | { |
379 | if (rownr == 0) |
380 | { |
381 | key[0]=1; /* null key */ |
382 | key[1]=0; /* Fore easy print of key */ |
383 | return; |
384 | } |
385 | *key++=0; |
386 | } |
387 | if (keyinfo[0].seg[0].flag & (HA_BLOB_PART | HA_VAR_LENGTH_PART)) |
388 | { |
389 | size_t tmp; |
390 | create_key_part(key+2,rownr); |
391 | tmp=strlen((char*) key+2); |
392 | int2store(key,tmp); |
393 | } |
394 | else |
395 | create_key_part(key,rownr); |
396 | } |
397 | |
398 | |
399 | static uchar blob_key[MAX_REC_LENGTH]; |
400 | static uchar blob_record[MAX_REC_LENGTH+20*20]; |
401 | |
402 | |
403 | static void create_record(uchar *record,uint rownr) |
404 | { |
405 | uchar *pos; |
406 | bzero((char*) record,MAX_REC_LENGTH); |
407 | record[0]=1; /* delete marker */ |
408 | if (rownr == 0 && keyinfo[0].seg[0].null_bit) |
409 | record[0]|=keyinfo[0].seg[0].null_bit; /* Null key */ |
410 | |
411 | pos=record+1; |
412 | if (recinfo[1].type == FIELD_BLOB) |
413 | { |
414 | size_t tmp; |
415 | uchar *ptr; |
416 | create_key_part(blob_key,rownr); |
417 | tmp=strlen((char*) blob_key); |
418 | int4store(pos,tmp); |
419 | ptr=blob_key; |
420 | memcpy(pos+4, &ptr, sizeof(char*)); |
421 | pos+=recinfo[1].length; |
422 | } |
423 | else if (recinfo[1].type == FIELD_VARCHAR) |
424 | { |
425 | size_t tmp, pack_length= HA_VARCHAR_PACKLENGTH(recinfo[1].length-1); |
426 | create_key_part(pos+pack_length,rownr); |
427 | tmp= strlen((char*) pos+pack_length); |
428 | if (pack_length == 1) |
429 | *(uchar*) pos= (uchar) tmp; |
430 | else |
431 | int2store(pos,tmp); |
432 | pos+= recinfo[1].length; |
433 | } |
434 | else |
435 | { |
436 | create_key_part(pos,rownr); |
437 | pos+=recinfo[1].length; |
438 | } |
439 | if (recinfo[2].type == FIELD_BLOB) |
440 | { |
441 | size_t tmp; |
442 | uchar *ptr;; |
443 | sprintf((char*) blob_record,"... row: %d" , rownr); |
444 | strappend((char*) blob_record,MY_MAX(MAX_REC_LENGTH-rownr,10),' '); |
445 | tmp=strlen((char*) blob_record); |
446 | int4store(pos,tmp); |
447 | ptr=blob_record; |
448 | memcpy(pos+4, &ptr, sizeof(char*)); |
449 | } |
450 | else if (recinfo[2].type == FIELD_VARCHAR) |
451 | { |
452 | size_t tmp, pack_length= HA_VARCHAR_PACKLENGTH(recinfo[1].length-1); |
453 | sprintf((char*) pos+pack_length, "... row: %d" , rownr); |
454 | tmp= strlen((char*) pos+pack_length); |
455 | if (pack_length == 1) |
456 | *pos= (uchar) tmp; |
457 | else |
458 | int2store(pos,tmp); |
459 | } |
460 | else |
461 | { |
462 | sprintf((char*) pos,"... row: %d" , rownr); |
463 | strappend((char*) pos,recinfo[2].length,' '); |
464 | } |
465 | } |
466 | |
467 | /* change row to test re-packing of rows and reallocation of keys */ |
468 | |
469 | static void update_record(uchar *record) |
470 | { |
471 | uchar *pos=record+1; |
472 | if (recinfo[1].type == FIELD_BLOB) |
473 | { |
474 | uchar *column,*ptr; |
475 | int length; |
476 | length=uint4korr(pos); /* Long blob */ |
477 | memcpy(&column, pos+4, sizeof(char*)); |
478 | memcpy(blob_key,column,length); /* Move old key */ |
479 | ptr=blob_key; |
480 | memcpy(pos+4, &ptr, sizeof(char*)); /* Store pointer to new key */ |
481 | if (keyinfo[0].seg[0].type != HA_KEYTYPE_NUM) |
482 | default_charset_info->cset->casedn(default_charset_info, |
483 | (char*) blob_key, length, |
484 | (char*) blob_key, length); |
485 | pos+=recinfo[1].length; |
486 | } |
487 | else if (recinfo[1].type == FIELD_VARCHAR) |
488 | { |
489 | uint pack_length= HA_VARCHAR_PACKLENGTH(recinfo[1].length-1); |
490 | uint length= pack_length == 1 ? (uint) *(uchar*) pos : uint2korr(pos); |
491 | default_charset_info->cset->casedn(default_charset_info, |
492 | (char*) pos + pack_length, length, |
493 | (char*) pos + pack_length, length); |
494 | pos+=recinfo[1].length; |
495 | } |
496 | else |
497 | { |
498 | if (keyinfo[0].seg[0].type != HA_KEYTYPE_NUM) |
499 | default_charset_info->cset->casedn(default_charset_info, |
500 | (char*) pos, keyinfo[0].seg[0].length, |
501 | (char*) pos, keyinfo[0].seg[0].length); |
502 | pos+=recinfo[1].length; |
503 | } |
504 | |
505 | if (recinfo[2].type == FIELD_BLOB) |
506 | { |
507 | uchar *column; |
508 | int length; |
509 | length=uint4korr(pos); |
510 | memcpy(&column, pos+4, sizeof(char*)); |
511 | memcpy(blob_record,column,length); |
512 | bfill(blob_record+length,20,'.'); /* Make it larger */ |
513 | length+=20; |
514 | int4store(pos,length); |
515 | column= blob_record; |
516 | memcpy(pos+4, &column, sizeof(char*)); |
517 | } |
518 | else if (recinfo[2].type == FIELD_VARCHAR) |
519 | { |
520 | /* Second field is longer than 10 characters */ |
521 | uint pack_length= HA_VARCHAR_PACKLENGTH(recinfo[1].length-1); |
522 | uint length= pack_length == 1 ? (uint) *(uchar*) pos : uint2korr(pos); |
523 | bfill(pos+pack_length+length,recinfo[2].length-length-pack_length,'.'); |
524 | length=recinfo[2].length-pack_length; |
525 | if (pack_length == 1) |
526 | *(uchar*) pos= (uchar) length; |
527 | else |
528 | int2store(pos,length); |
529 | } |
530 | else |
531 | { |
532 | bfill(pos+recinfo[2].length-10,10,'.'); |
533 | } |
534 | } |
535 | |
536 | |
537 | static struct my_option my_long_options[] = |
538 | { |
539 | {"checksum" , 'c', "Undocumented" , |
540 | 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, |
541 | #ifndef DBUG_OFF |
542 | {"debug" , '#', "Undocumented" , |
543 | 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, |
544 | #endif |
545 | {"delete_rows" , 'd', "Undocumented" , &remove_count, |
546 | &remove_count, 0, GET_UINT, REQUIRED_ARG, 1000, 0, 0, 0, 0, 0}, |
547 | {"help" , '?', "Display help and exit" , |
548 | 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, |
549 | {"insert_rows" , 'i', "Undocumented" , &insert_count, |
550 | &insert_count, 0, GET_UINT, REQUIRED_ARG, 1000, 0, 0, 0, 0, 0}, |
551 | {"key_alpha" , 'a', "Use a key of type HA_KEYTYPE_TEXT" , |
552 | 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, |
553 | {"key_binary_pack" , 'B', "Undocumented" , |
554 | 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, |
555 | {"key_blob" , 'b', "Undocumented" , |
556 | 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, |
557 | {"key_cache" , 'K', "Undocumented" , &key_cacheing, |
558 | &key_cacheing, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, |
559 | {"key_length" , 'k', "Undocumented" , &key_length, &key_length, |
560 | 0, GET_UINT, REQUIRED_ARG, 6, 0, 0, 0, 0, 0}, |
561 | {"key_multiple" , 'm', "Undocumented" , |
562 | 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, |
563 | {"key_prefix_pack" , 'P', "Undocumented" , |
564 | 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, |
565 | {"key_space_pack" , 'p', "Undocumented" , |
566 | 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, |
567 | {"key_varchar" , 'w', "Test VARCHAR keys" , |
568 | 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, |
569 | {"null_fields" , 'N', "Define fields with NULL" , |
570 | &null_fields, &null_fields, 0, GET_BOOL, NO_ARG, |
571 | 0, 0, 0, 0, 0, 0}, |
572 | {"row_fixed_size" , 'S', "Undocumented" , |
573 | 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, |
574 | {"row_pointer_size" , 'R', "Undocumented" , &rec_pointer_size, |
575 | &rec_pointer_size, 0, GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, |
576 | {"silent" , 's', "Undocumented" , |
577 | &silent, &silent, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, |
578 | {"skip_update" , 'U', "Undocumented" , &skip_update, |
579 | &skip_update, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, |
580 | {"unique" , 'C', "Undocumented" , &opt_unique, &opt_unique, 0, |
581 | GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, |
582 | {"update_rows" , 'u', "Undocumented" , &update_count, |
583 | &update_count, 0, GET_UINT, REQUIRED_ARG, 1000, 0, 0, 0, 0, 0}, |
584 | {"verbose" , 'v', "Be more verbose" , &verbose, &verbose, 0, |
585 | GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, |
586 | {"version" , 'V', "Print version number and exit" , |
587 | 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, |
588 | { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} |
589 | }; |
590 | |
591 | |
592 | static my_bool |
593 | get_one_option(int optid, const struct my_option *opt __attribute__((unused)), |
594 | char *argument __attribute__((unused))) |
595 | { |
596 | switch(optid) { |
597 | case 'a': |
598 | key_type= HA_KEYTYPE_TEXT; |
599 | break; |
600 | case 'c': |
601 | create_flag|= HA_CREATE_CHECKSUM; |
602 | break; |
603 | case 'R': /* Length of record pointer */ |
604 | if (rec_pointer_size > 3) |
605 | rec_pointer_size=0; |
606 | break; |
607 | case 'P': |
608 | pack_keys= HA_PACK_KEY; /* Use prefix compression */ |
609 | break; |
610 | case 'B': |
611 | pack_keys= HA_BINARY_PACK_KEY; /* Use binary compression */ |
612 | break; |
613 | case 'S': |
614 | if (key_field == FIELD_VARCHAR) |
615 | { |
616 | create_flag=0; /* Static sized varchar */ |
617 | } |
618 | else if (key_field != FIELD_BLOB) |
619 | { |
620 | key_field=FIELD_NORMAL; /* static-size record */ |
621 | extra_field=FIELD_NORMAL; |
622 | } |
623 | break; |
624 | case 'p': |
625 | pack_keys=HA_PACK_KEY; /* Use prefix + space packing */ |
626 | pack_seg=HA_SPACE_PACK; |
627 | key_type=HA_KEYTYPE_TEXT; |
628 | break; |
629 | case 'm': |
630 | unique_key=0; |
631 | break; |
632 | case 'b': |
633 | key_field=FIELD_BLOB; /* blob key */ |
634 | extra_field= FIELD_BLOB; |
635 | pack_seg|= HA_BLOB_PART; |
636 | key_type= HA_KEYTYPE_VARTEXT1; |
637 | break; |
638 | case 'k': |
639 | if (key_length < 4 || key_length > HA_MAX_KEY_LENGTH) |
640 | { |
641 | fprintf(stderr,"Wrong key length\n" ); |
642 | exit(1); |
643 | } |
644 | break; |
645 | case 'w': |
646 | key_field=FIELD_VARCHAR; /* varchar keys */ |
647 | extra_field= FIELD_VARCHAR; |
648 | key_type= HA_KEYTYPE_VARTEXT1; |
649 | pack_seg|= HA_VAR_LENGTH_PART; |
650 | create_flag|= HA_PACK_RECORD; |
651 | break; |
652 | case 'K': /* Use key cacheing */ |
653 | key_cacheing=1; |
654 | break; |
655 | case 'V': |
656 | printf("test1 Ver 1.2 \n" ); |
657 | exit(0); |
658 | case '#': |
659 | DBUG_PUSH (argument); |
660 | break; |
661 | case '?': |
662 | usage(); |
663 | exit(1); |
664 | } |
665 | return 0; |
666 | } |
667 | |
668 | |
669 | /* Read options */ |
670 | |
671 | static void get_options(int argc, char *argv[]) |
672 | { |
673 | int ho_error; |
674 | |
675 | if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option))) |
676 | exit(ho_error); |
677 | |
678 | return; |
679 | } /* get options */ |
680 | |
681 | |
682 | static void usage() |
683 | { |
684 | printf("Usage: %s [options]\n\n" , my_progname); |
685 | my_print_help(my_long_options); |
686 | my_print_variables(my_long_options); |
687 | } |
688 | |
689 | #include "mi_extrafunc.h" |
690 | |