1 | /* Copyright (C) 2006 MySQL AB & MySQL Finland AB & TCX DataKonsult AB |
2 | |
3 | This program is free software; you can redistribute it and/or modify |
4 | it under the terms of the GNU General Public License as published by |
5 | the Free Software Foundation; version 2 of the License. |
6 | |
7 | This program is distributed in the hope that it will be useful, |
8 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
9 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
10 | GNU General Public License for more details. |
11 | |
12 | You should have received a copy of the GNU General Public License |
13 | along with this program; if not, write to the Free Software |
14 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ |
15 | |
16 | /* Testing of the basic functions of a MARIA rtree table */ |
17 | /* Written by Alex Barkov who has a shared copyright to this code */ |
18 | |
19 | |
20 | #include "maria_def.h" |
21 | #include "ma_control_file.h" |
22 | #include "ma_loghandler.h" |
23 | #include "ma_checkpoint.h" |
24 | #include "trnman.h" |
25 | #include <my_getopt.h> |
26 | |
27 | #ifdef HAVE_RTREE_KEYS |
28 | |
29 | #include "ma_rt_index.h" |
30 | |
31 | #define MAX_REC_LENGTH 1024 |
32 | #define ndims 2 |
33 | #define KEYALG HA_KEY_ALG_RTREE |
34 | |
35 | static int read_with_pos(MARIA_HA * file); |
36 | static void create_record(uchar *record,uint rownr); |
37 | static void create_record1(uchar *record,uint rownr); |
38 | static void print_record(uchar * record,my_off_t offs,const char * tail); |
39 | static int run_test(const char *filename); |
40 | static void get_options(int argc, char *argv[]); |
41 | static void usage(); |
42 | |
43 | static double rt_data[]= |
44 | { |
45 | /*1*/ 0,10,0,10, |
46 | /*2*/ 5,15,0,10, |
47 | /*3*/ 0,10,5,15, |
48 | /*4*/ 10,20,10,20, |
49 | /*5*/ 0,10,0,10, |
50 | /*6*/ 5,15,0,10, |
51 | /*7*/ 0,10,5,15, |
52 | /*8*/ 10,20,10,20, |
53 | /*9*/ 0,10,0,10, |
54 | /*10*/ 5,15,0,10, |
55 | /*11*/ 0,10,5,15, |
56 | /*12*/ 10,20,10,20, |
57 | /*13*/ 0,10,0,10, |
58 | /*14*/ 5,15,0,10, |
59 | /*15*/ 0,10,5,15, |
60 | /*16*/ 10,20,10,20, |
61 | /*17*/ 5,15,0,10, |
62 | /*18*/ 0,10,5,15, |
63 | /*19*/ 10,20,10,20, |
64 | /*20*/ 0,10,0,10, |
65 | |
66 | /*1*/ 100,110,0,10, |
67 | /*2*/ 105,115,0,10, |
68 | /*3*/ 100,110,5,15, |
69 | /*4*/ 110,120,10,20, |
70 | /*5*/ 100,110,0,10, |
71 | /*6*/ 105,115,0,10, |
72 | /*7*/ 100,110,5,15, |
73 | /*8*/ 110,120,10,20, |
74 | /*9*/ 100,110,0,10, |
75 | /*10*/ 105,115,0,10, |
76 | /*11*/ 100,110,5,15, |
77 | /*12*/ 110,120,10,20, |
78 | /*13*/ 100,110,0,10, |
79 | /*14*/ 105,115,0,10, |
80 | /*15*/ 100,110,5,15, |
81 | /*16*/ 110,120,10,20, |
82 | /*17*/ 105,115,0,10, |
83 | /*18*/ 100,110,5,15, |
84 | /*19*/ 110,120,10,20, |
85 | /*20*/ 100,110,0,10, |
86 | -1 |
87 | }; |
88 | |
89 | static int testflag, checkpoint, create_flag; |
90 | static my_bool silent, transactional, die_in_middle_of_transaction, |
91 | opt_versioning; |
92 | static enum data_file_type record_type= DYNAMIC_RECORD; |
93 | |
94 | int main(int argc, char *argv[]) |
95 | { |
96 | char buff[FN_REFLEN]; |
97 | MY_INIT(argv[0]); |
98 | maria_data_root= (char *)"." ; |
99 | get_options(argc, argv); |
100 | /* Maria requires that we always have a page cache */ |
101 | if (maria_init() || |
102 | (init_pagecache(maria_pagecache, maria_block_size * 16, 0, 0, |
103 | maria_block_size, 0, MY_WME) == 0) || |
104 | ma_control_file_open(TRUE, TRUE) || |
105 | (init_pagecache(maria_log_pagecache, |
106 | TRANSLOG_PAGECACHE_SIZE, 0, 0, |
107 | TRANSLOG_PAGE_SIZE, 0, MY_WME) == 0) || |
108 | translog_init(maria_data_root, TRANSLOG_FILE_SIZE, |
109 | 0, 0, maria_log_pagecache, |
110 | TRANSLOG_DEFAULT_FLAGS, 0) || |
111 | (transactional && (trnman_init(0) || ma_checkpoint_init(0)))) |
112 | { |
113 | fprintf(stderr, "Error in initialization\n" ); |
114 | exit(1); |
115 | } |
116 | |
117 | exit(run_test(fn_format(buff, "test1" , maria_data_root, "" , MYF(0)))); |
118 | } |
119 | |
120 | |
121 | static int run_test(const char *filename) |
122 | { |
123 | MARIA_HA *file; |
124 | MARIA_UNIQUEDEF uniquedef; |
125 | MARIA_CREATE_INFO create_info; |
126 | MARIA_COLUMNDEF recinfo[20]; |
127 | MARIA_KEYDEF keyinfo[20]; |
128 | HA_KEYSEG keyseg[20]; |
129 | key_range range; |
130 | |
131 | int opt_unique=0; |
132 | int key_type=HA_KEYTYPE_DOUBLE; |
133 | int key_length=8; |
134 | int null_fields=0; |
135 | int nrecords=sizeof(rt_data)/(sizeof(double)*4);/* 40 */ |
136 | int rec_length=0; |
137 | int uniques=0; |
138 | int i, max_i; |
139 | int error; |
140 | int row_count=0; |
141 | uchar record[MAX_REC_LENGTH]; |
142 | uchar read_record[MAX_REC_LENGTH]; |
143 | int upd= 10; |
144 | ha_rows hrows; |
145 | |
146 | bzero(&uniquedef, sizeof(uniquedef)); |
147 | bzero(&create_info, sizeof(create_info)); |
148 | bzero(recinfo, sizeof(recinfo)); |
149 | bzero(keyinfo, sizeof(keyinfo)); |
150 | bzero(keyseg, sizeof(keyseg)); |
151 | |
152 | /* Define a column for NULLs and DEL markers*/ |
153 | |
154 | recinfo[0].type=FIELD_NORMAL; |
155 | recinfo[0].length=1; /* For NULL bits */ |
156 | rec_length=1; |
157 | |
158 | /* Define 2*ndims columns for coordinates*/ |
159 | |
160 | for (i=1; i<=2*ndims ;i++) |
161 | { |
162 | recinfo[i].type=FIELD_NORMAL; |
163 | recinfo[i].length=key_length; |
164 | rec_length+=key_length; |
165 | } |
166 | |
167 | /* Define a key with 2*ndims segments */ |
168 | |
169 | keyinfo[0].seg=keyseg; |
170 | keyinfo[0].keysegs=2*ndims; |
171 | keyinfo[0].flag=0; |
172 | keyinfo[0].key_alg=KEYALG; |
173 | |
174 | for (i=0; i<2*ndims; i++) |
175 | { |
176 | keyinfo[0].seg[i].type= key_type; |
177 | keyinfo[0].seg[i].flag=0; /* Things like HA_REVERSE_SORT */ |
178 | keyinfo[0].seg[i].start= (key_length*i)+1; |
179 | keyinfo[0].seg[i].length=key_length; |
180 | keyinfo[0].seg[i].null_bit= null_fields ? 2 : 0; |
181 | keyinfo[0].seg[i].null_pos=0; |
182 | keyinfo[0].seg[i].language=default_charset_info->number; |
183 | } |
184 | |
185 | if (!silent) |
186 | printf("- Creating isam-file\n" ); |
187 | |
188 | create_info.max_rows=10000000; |
189 | create_info.transactional= transactional; |
190 | |
191 | if (maria_create(filename, |
192 | record_type, |
193 | 1, /* keys */ |
194 | keyinfo, |
195 | 1+2*ndims+opt_unique, /* columns */ |
196 | recinfo,uniques,&uniquedef,&create_info,create_flag)) |
197 | goto err; |
198 | |
199 | if (!silent) |
200 | printf("- Open isam-file\n" ); |
201 | |
202 | if (!(file=maria_open(filename,2,HA_OPEN_ABORT_IF_LOCKED))) |
203 | goto err; |
204 | maria_begin(file); |
205 | if (opt_versioning) |
206 | maria_versioning(file, 1); |
207 | if (testflag == 1) |
208 | goto end; |
209 | if (checkpoint == 1 && ma_checkpoint_execute(CHECKPOINT_MEDIUM, FALSE)) |
210 | goto err; |
211 | if (!silent) |
212 | printf("- Writing key:s\n" ); |
213 | |
214 | for (i=0; i<nrecords; i++ ) |
215 | { |
216 | create_record(record,i); |
217 | error=maria_write(file,record); |
218 | print_record(record,maria_position(file),"\n" ); |
219 | if (!error) |
220 | { |
221 | row_count++; |
222 | } |
223 | else |
224 | { |
225 | fprintf(stderr, "maria_write: %d\n" , error); |
226 | goto err; |
227 | } |
228 | } |
229 | |
230 | if (maria_scan_init(file)) |
231 | { |
232 | fprintf(stderr, "maria_scan_init failed\n" ); |
233 | goto err; |
234 | } |
235 | if ((error=read_with_pos(file))) |
236 | goto err; |
237 | maria_scan_end(file); |
238 | |
239 | if (!silent) |
240 | printf("- Reading rows with key\n" ); |
241 | |
242 | for (i=0 ; i < nrecords ; i++) |
243 | { |
244 | my_errno=0; |
245 | create_record(record,i); |
246 | |
247 | bzero((char*) read_record,MAX_REC_LENGTH); |
248 | error=maria_rkey(file,read_record,0,record+1,HA_WHOLE_KEY,HA_READ_MBR_EQUAL); |
249 | |
250 | if (error && error!=HA_ERR_KEY_NOT_FOUND) |
251 | { |
252 | fprintf(stderr," maria_rkey: %3d errno: %3d\n" ,error,my_errno); |
253 | goto err; |
254 | } |
255 | if (error == HA_ERR_KEY_NOT_FOUND) |
256 | { |
257 | print_record(record,maria_position(file)," NOT FOUND\n" ); |
258 | continue; |
259 | } |
260 | print_record(read_record,maria_position(file),"\n" ); |
261 | } |
262 | |
263 | if (checkpoint == 2 && ma_checkpoint_execute(CHECKPOINT_MEDIUM, FALSE)) |
264 | goto err; |
265 | |
266 | if (testflag == 2) |
267 | goto end; |
268 | |
269 | if (!silent) |
270 | printf("- Deleting rows\n" ); |
271 | if (maria_scan_init(file)) |
272 | { |
273 | fprintf(stderr, "maria_scan_init failed\n" ); |
274 | goto err; |
275 | } |
276 | |
277 | for (i=0; i < nrecords/4; i++) |
278 | { |
279 | my_errno=0; |
280 | bzero((char*) read_record,MAX_REC_LENGTH); |
281 | error=maria_scan(file,read_record); |
282 | if (error) |
283 | { |
284 | fprintf(stderr, "pos: %2d maria_rrnd: %3d errno: %3d\n" , i, error, |
285 | my_errno); |
286 | goto err; |
287 | } |
288 | print_record(read_record,maria_position(file),"\n" ); |
289 | |
290 | error=maria_delete(file,read_record); |
291 | if (error) |
292 | { |
293 | fprintf(stderr, "pos: %2d maria_delete: %3d errno: %3d\n" , i, error, |
294 | my_errno); |
295 | goto err; |
296 | } |
297 | } |
298 | maria_scan_end(file); |
299 | |
300 | if (testflag == 3) |
301 | goto end; |
302 | if (checkpoint == 3 && ma_checkpoint_execute(CHECKPOINT_MEDIUM, FALSE)) |
303 | goto err; |
304 | |
305 | if (!silent) |
306 | printf("- Updating rows with position\n" ); |
307 | if (maria_scan_init(file)) |
308 | { |
309 | fprintf(stderr, "maria_scan_init failed\n" ); |
310 | goto err; |
311 | } |
312 | |
313 | /* We are looking for nrecords-necords/2 non-deleted records */ |
314 | for (i=0, max_i= nrecords - nrecords/2; i < max_i ; i++) |
315 | { |
316 | my_errno=0; |
317 | bzero((char*) read_record,MAX_REC_LENGTH); |
318 | error=maria_scan(file,read_record); |
319 | if (error) |
320 | { |
321 | if (error==HA_ERR_RECORD_DELETED) |
322 | { |
323 | if (!silent) |
324 | printf("found deleted record\n" ); |
325 | /* |
326 | In BLOCK_RECORD format, maria_scan() never returns deleted records, |
327 | while in DYNAMIC format it can. Don't count such record: |
328 | */ |
329 | max_i++; |
330 | continue; |
331 | } |
332 | fprintf(stderr, "pos: %2d maria_rrnd: %3d errno: %3d\n" ,i , error, |
333 | my_errno); |
334 | goto err; |
335 | } |
336 | print_record(read_record,maria_position(file),"" ); |
337 | create_record1(record,i+nrecords*upd); |
338 | if (!silent) |
339 | printf("\t-> " ); |
340 | print_record(record,maria_position(file),"\n" ); |
341 | error=maria_update(file,read_record,record); |
342 | if (error) |
343 | { |
344 | fprintf(stderr, "pos: %2d maria_update: %3d errno: %3d\n" ,i, error, |
345 | my_errno); |
346 | goto err; |
347 | } |
348 | } |
349 | |
350 | if (testflag == 4) |
351 | goto end; |
352 | if (checkpoint == 4 && ma_checkpoint_execute(CHECKPOINT_MEDIUM, FALSE)) |
353 | goto err; |
354 | |
355 | if (maria_scan_init(file)) |
356 | { |
357 | fprintf(stderr, "maria_scan_init failed\n" ); |
358 | goto err; |
359 | } |
360 | if ((error=read_with_pos(file))) |
361 | goto err; |
362 | maria_scan_end(file); |
363 | |
364 | if (!silent) |
365 | printf("- Test maria_rkey then a sequence of maria_rnext_same\n" ); |
366 | |
367 | create_record(record, nrecords*4/5); |
368 | print_record(record,0," search for\n" ); |
369 | |
370 | if ((error=maria_rkey(file,read_record,0,record+1,HA_WHOLE_KEY, |
371 | HA_READ_MBR_INTERSECT))) |
372 | { |
373 | fprintf(stderr, "maria_rkey: %3d errno: %3d\n" ,error,my_errno); |
374 | goto err; |
375 | } |
376 | print_record(read_record,maria_position(file)," maria_rkey\n" ); |
377 | row_count=1; |
378 | |
379 | for (;;) |
380 | { |
381 | if ((error=maria_rnext_same(file,read_record))) |
382 | { |
383 | if (error==HA_ERR_END_OF_FILE) |
384 | break; |
385 | fprintf(stderr, "maria_next: %3d errno: %3d\n" ,error,my_errno); |
386 | goto err; |
387 | } |
388 | print_record(read_record,maria_position(file)," maria_rnext_same\n" ); |
389 | row_count++; |
390 | } |
391 | if (!silent) |
392 | printf(" %d rows\n" ,row_count); |
393 | |
394 | if (!silent) |
395 | printf("- Test maria_rfirst then a sequence of maria_rnext\n" ); |
396 | |
397 | error=maria_rfirst(file,read_record,0); |
398 | if (error) |
399 | { |
400 | fprintf(stderr, "maria_rfirst: %3d errno: %3d\n" ,error,my_errno); |
401 | goto err; |
402 | } |
403 | row_count=1; |
404 | print_record(read_record,maria_position(file)," maria_frirst\n" ); |
405 | |
406 | for (i=0;i<nrecords;i++) |
407 | { |
408 | if ((error=maria_rnext(file,read_record,0))) |
409 | { |
410 | if (error==HA_ERR_END_OF_FILE) |
411 | break; |
412 | fprintf(stderr, "maria_next: %3d errno: %3d\n" ,error,my_errno); |
413 | goto err; |
414 | } |
415 | print_record(read_record,maria_position(file)," maria_rnext\n" ); |
416 | row_count++; |
417 | } |
418 | if (!silent) |
419 | printf(" %d rows\n" ,row_count); |
420 | |
421 | if (!silent) |
422 | printf("- Test maria_records_in_range()\n" ); |
423 | |
424 | create_record1(record, nrecords*4/5); |
425 | print_record(record,0,"\n" ); |
426 | |
427 | range.key= record+1; |
428 | range.length= 1000; /* Big enough */ |
429 | range.flag= HA_READ_MBR_INTERSECT; |
430 | hrows= maria_records_in_range(file,0, &range, (key_range*) 0); |
431 | if (!silent) |
432 | printf(" %ld rows\n" , (long) hrows); |
433 | |
434 | end: |
435 | maria_scan_end(file); |
436 | if (die_in_middle_of_transaction) |
437 | { |
438 | /* see similar code in ma_test2.c for comments */ |
439 | switch (die_in_middle_of_transaction) { |
440 | case 1: |
441 | _ma_flush_table_files(file, MARIA_FLUSH_DATA | MARIA_FLUSH_INDEX, |
442 | FLUSH_RELEASE, FLUSH_RELEASE); |
443 | break; |
444 | case 2: |
445 | if (translog_flush(file->trn->undo_lsn)) |
446 | goto err; |
447 | break; |
448 | case 3: |
449 | break; |
450 | case 4: |
451 | _ma_flush_table_files(file, MARIA_FLUSH_DATA, FLUSH_RELEASE, |
452 | FLUSH_RELEASE); |
453 | if (translog_flush(file->trn->undo_lsn)) |
454 | goto err; |
455 | break; |
456 | } |
457 | if (!silent) |
458 | printf("Dying on request without maria_commit()/maria_close()\n" ); |
459 | exit(0); |
460 | } |
461 | if (maria_commit(file)) |
462 | goto err; |
463 | if (maria_close(file)) goto err; |
464 | maria_end(); |
465 | my_end(MY_CHECK_ERROR); |
466 | |
467 | return 0; |
468 | |
469 | err: |
470 | fprintf(stderr, "got error: %3d when using maria-database\n" ,my_errno); |
471 | return 1; /* skip warning */ |
472 | } |
473 | |
474 | |
475 | |
476 | static int read_with_pos (MARIA_HA * file) |
477 | { |
478 | int error; |
479 | int i; |
480 | uchar read_record[MAX_REC_LENGTH]; |
481 | |
482 | if (!silent) |
483 | printf("- Reading rows with position\n" ); |
484 | for (i=0;;i++) |
485 | { |
486 | my_errno=0; |
487 | bzero((char*) read_record,MAX_REC_LENGTH); |
488 | error=maria_scan(file,read_record); |
489 | if (error) |
490 | { |
491 | if (error==HA_ERR_END_OF_FILE) |
492 | break; |
493 | if (error==HA_ERR_RECORD_DELETED) |
494 | continue; |
495 | fprintf(stderr, "pos: %2d maria_rrnd: %3d errno: %3d\n" , i, error, |
496 | my_errno); |
497 | return error; |
498 | } |
499 | print_record(read_record,maria_position(file),"\n" ); |
500 | } |
501 | return 0; |
502 | } |
503 | |
504 | |
505 | #ifdef NOT_USED |
506 | static void bprint_record(char * record, |
507 | my_off_t offs __attribute__((unused)), |
508 | const char * tail) |
509 | { |
510 | int i; |
511 | char * pos; |
512 | if (silent) |
513 | return; |
514 | i=(unsigned char)record[0]; |
515 | printf("%02X " ,i); |
516 | |
517 | for( pos=record+1, i=0; i<32; i++,pos++){ |
518 | int b=(unsigned char)*pos; |
519 | printf("%02X" ,b); |
520 | } |
521 | printf("%s" ,tail); |
522 | } |
523 | #endif |
524 | |
525 | |
526 | static void print_record(uchar *record, |
527 | my_off_t offs __attribute__((unused)), |
528 | const char * tail) |
529 | { |
530 | int i; |
531 | uchar *pos; |
532 | double c; |
533 | |
534 | if (silent) |
535 | return; |
536 | printf(" rec=(%d)" ,(unsigned char)record[0]); |
537 | for ( pos=record+1, i=0; i<2*ndims; i++) |
538 | { |
539 | memcpy(&c,pos,sizeof(c)); |
540 | float8get(c,pos); |
541 | printf(" %.14g " ,c); |
542 | pos+=sizeof(c); |
543 | } |
544 | printf("pos=%ld" ,(long int)offs); |
545 | printf("%s" ,tail); |
546 | } |
547 | |
548 | |
549 | |
550 | static void create_record1(uchar *record, uint rownr) |
551 | { |
552 | int i; |
553 | uchar *pos; |
554 | double c=rownr+10; |
555 | |
556 | bzero((char*) record,MAX_REC_LENGTH); |
557 | record[0]=0x01; /* DEL marker */ |
558 | |
559 | for ( pos=record+1, i=0; i<2*ndims; i++) |
560 | { |
561 | memcpy(pos,&c,sizeof(c)); |
562 | float8store(pos,c); |
563 | pos+=sizeof(c); |
564 | } |
565 | } |
566 | |
567 | #ifdef NOT_USED |
568 | |
569 | static void create_record0(char *record,uint rownr) |
570 | { |
571 | int i; |
572 | char * pos; |
573 | double c=rownr+10; |
574 | double c0=0; |
575 | |
576 | bzero((char*) record,MAX_REC_LENGTH); |
577 | record[0]=0x01; /* DEL marker */ |
578 | |
579 | for ( pos=record+1, i=0; i<ndims; i++) |
580 | { |
581 | memcpy(pos,&c0,sizeof(c0)); |
582 | float8store(pos,c0); |
583 | pos+=sizeof(c0); |
584 | memcpy(pos,&c,sizeof(c)); |
585 | float8store(pos,c); |
586 | pos+=sizeof(c); |
587 | } |
588 | } |
589 | |
590 | #endif |
591 | |
592 | static void create_record(uchar *record, uint rownr) |
593 | { |
594 | int i; |
595 | uchar *pos; |
596 | double *data= rt_data+rownr*4; |
597 | record[0]=0x01; /* DEL marker */ |
598 | for ( pos=record+1, i=0; i<ndims*2; i++) |
599 | { |
600 | float8store(pos,data[i]); |
601 | pos+=8; |
602 | } |
603 | } |
604 | |
605 | |
606 | static struct my_option my_long_options[] = |
607 | { |
608 | {"checkpoint" , 'H', "Checkpoint at specified stage" , (uchar**) &checkpoint, |
609 | (uchar**) &checkpoint, 0, GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, |
610 | {"checksum" , 'c', "Undocumented" , |
611 | 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, |
612 | #ifndef DBUG_OFF |
613 | {"debug" , '#', "Undocumented" , |
614 | 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, |
615 | #endif |
616 | {"help" , '?', "Display help and exit" , |
617 | 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, |
618 | {"datadir" , 'h', "Path to the database root." , &maria_data_root, |
619 | &maria_data_root, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, |
620 | {"row-fixed-size" , 'S', "Fixed size records" , |
621 | 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, |
622 | {"rows-in-block" , 'M', "Store rows in block format" , |
623 | 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, |
624 | {"silent" , 's', "Undocumented" , |
625 | (uchar**) &silent, (uchar**) &silent, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, |
626 | 0, 0}, |
627 | {"testflag" , 't', "Stop test at specified stage" , (uchar**) &testflag, |
628 | (uchar**) &testflag, 0, GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, |
629 | {"test-undo" , 'A', |
630 | "Abort hard. Used for testing recovery with undo" , |
631 | (uchar**) &die_in_middle_of_transaction, |
632 | (uchar**) &die_in_middle_of_transaction, |
633 | 0, GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, |
634 | {"transactional" , 'T', |
635 | "Test in transactional mode. (Only works with block format)" , |
636 | (uchar**) &transactional, (uchar**) &transactional, 0, GET_BOOL, NO_ARG, |
637 | 0, 0, 0, 0, 0, 0}, |
638 | {"versioning" , 'C', "Use row versioning (only works with block format)" , |
639 | (uchar**) &opt_versioning, (uchar**) &opt_versioning, 0, GET_BOOL, |
640 | NO_ARG, 0, 0, 0, 0, 0, 0}, |
641 | { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} |
642 | }; |
643 | |
644 | |
645 | static my_bool |
646 | get_one_option(int optid, const struct my_option *opt __attribute__((unused)), |
647 | char *argument __attribute__((unused))) |
648 | { |
649 | switch(optid) { |
650 | case 'c': |
651 | create_flag|= HA_CREATE_CHECKSUM | HA_CREATE_PAGE_CHECKSUM; |
652 | break; |
653 | case 'M': |
654 | record_type= BLOCK_RECORD; |
655 | break; |
656 | case 'S': |
657 | record_type= STATIC_RECORD; |
658 | break; |
659 | case '#': |
660 | DBUG_PUSH(argument); |
661 | break; |
662 | case '?': |
663 | usage(); |
664 | exit(1); |
665 | } |
666 | return 0; |
667 | } |
668 | |
669 | |
670 | /* Read options */ |
671 | |
672 | static void get_options(int argc, char *argv[]) |
673 | { |
674 | int ho_error; |
675 | |
676 | if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option))) |
677 | exit(ho_error); |
678 | |
679 | return; |
680 | } /* get options */ |
681 | |
682 | |
683 | static void usage() |
684 | { |
685 | printf("Usage: %s [options]\n\n" , my_progname); |
686 | my_print_help(my_long_options); |
687 | my_print_variables(my_long_options); |
688 | } |
689 | |
690 | #include "ma_check_standalone.h" |
691 | |
692 | #else |
693 | int main(int argc __attribute__((unused)),char *argv[] __attribute__((unused))) |
694 | { |
695 | exit(0); |
696 | } |
697 | #endif /*HAVE_RTREE_KEYS*/ |
698 | |