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