diff options
author | unknown <monty@hundin.mysql.fi> | 2002-06-03 12:59:31 +0300 |
---|---|---|
committer | unknown <monty@hundin.mysql.fi> | 2002-06-03 12:59:31 +0300 |
commit | f0409fa920c7908f2f9ef03919583a32bf84eaad (patch) | |
tree | be04186411dc657ef6bbcbe01267d30f2675c914 /myisam | |
parent | ebbcb0f391d7df364e0ccc6bca706456e9aadbf7 (diff) | |
parent | 7cb2e2d1dce2c7466388f4a6ade0614564be82fc (diff) | |
download | mariadb-git-f0409fa920c7908f2f9ef03919583a32bf84eaad.tar.gz |
merge with 4.0
BitKeeper/etc/ignore:
auto-union
BitKeeper/etc/logging_ok:
auto-union
BUILD/SETUP.sh:
Auto merged
BUILD/compile-pentium-debug:
Auto merged
BitKeeper/triggers/post-commit:
Auto merged
configure.in:
Auto merged
Docs/manual.texi:
Auto merged
client/mysql.cc:
Auto merged
client/mysqldump.c:
Auto merged
client/mysqltest.c:
Auto merged
extra/mysql_install.c:
Auto merged
extra/resolve_stack_dump.c:
Auto merged
extra/resolveip.c:
Auto merged
include/my_sys.h:
Auto merged
include/mysqld_error.h:
Auto merged
isam/pack_isam.c:
Auto merged
libmysql/Makefile.shared:
Auto merged
libmysql/libmysql.c:
Auto merged
myisam/ft_dump.c:
Auto merged
myisam/ft_test1.c:
Auto merged
myisam/ftdefs.h:
Auto merged
myisam/mi_check.c:
Auto merged
myisam/mi_test1.c:
Auto merged
myisam/mi_write.c:
Auto merged
myisam/myisamchk.c:
Auto merged
myisam/myisampack.c:
Auto merged
mysql-test/mysql-test-run.sh:
Auto merged
mysql-test/r/select_found.result:
Auto merged
mysql-test/t/select_found.test:
Auto merged
mysys/charset.c:
Auto merged
mysys/default.c:
Auto merged
mysys/hash.c:
Auto merged
sql/field.cc:
Auto merged
sql/gen_lex_hash.cc:
Auto merged
sql/ha_innodb.cc:
Auto merged
sql/hostname.cc:
Auto merged
sql/item_cmpfunc.h:
Auto merged
sql/item_strfunc.cc:
Auto merged
sql/item_timefunc.h:
Auto merged
sql/lex.h:
Auto merged
sql/log.cc:
Auto merged
sql/mysql_priv.h:
Auto merged
sql/repl_failsafe.cc:
Auto merged
sql/slave.cc:
Auto merged
sql/sql_acl.cc:
Auto merged
sql/sql_base.cc:
Auto merged
sql/sql_cache.cc:
Auto merged
sql/sql_class.cc:
Auto merged
sql/sql_class.h:
Auto merged
sql/sql_db.cc:
Auto merged
sql/sql_parse.cc:
Auto merged
sql/sql_select.cc:
Auto merged
sql/sql_string.cc:
Auto merged
sql/sql_table.cc:
Auto merged
sql/sql_union.cc:
Auto merged
sql/share/czech/errmsg.txt:
Auto merged
sql/share/danish/errmsg.txt:
Auto merged
sql/share/dutch/errmsg.txt:
Auto merged
sql/share/english/errmsg.txt:
Auto merged
sql/share/estonian/errmsg.txt:
Auto merged
sql/share/german/errmsg.txt:
Auto merged
sql/share/greek/errmsg.txt:
Auto merged
sql/share/hungarian/errmsg.txt:
Auto merged
sql/share/italian/errmsg.txt:
Auto merged
sql/share/japanese/errmsg.txt:
Auto merged
sql/share/korean/errmsg.txt:
Auto merged
sql/share/norwegian-ny/errmsg.txt:
Auto merged
sql/share/norwegian/errmsg.txt:
Auto merged
sql/sql_update.cc:
Auto merged
sql/structs.h:
Auto merged
sql/share/polish/errmsg.txt:
Auto merged
sql/share/portuguese/errmsg.txt:
Auto merged
sql/share/romanian/errmsg.txt:
Auto merged
sql/share/russian/errmsg.txt:
Auto merged
sql/share/slovak/errmsg.txt:
Auto merged
sql/share/spanish/errmsg.txt:
Auto merged
sql/share/swedish/errmsg.txt:
Auto merged
sql/share/ukrainian/errmsg.txt:
Auto merged
strings/Makefile.am:
Auto merged
strings/ctype-ujis.c:
Auto merged
tools/mysqlmanager.c:
Auto merged
Diffstat (limited to 'myisam')
-rw-r--r-- | myisam/ft_boolean_search.c | 182 | ||||
-rw-r--r-- | myisam/ft_dump.c | 103 | ||||
-rw-r--r-- | myisam/ft_eval.c | 125 | ||||
-rw-r--r-- | myisam/ft_nlq_search.c | 10 | ||||
-rw-r--r-- | myisam/ft_parser.c | 33 | ||||
-rw-r--r-- | myisam/ft_test1.c | 88 | ||||
-rw-r--r-- | myisam/ft_update.c | 19 | ||||
-rw-r--r-- | myisam/ftdefs.h | 6 | ||||
-rw-r--r-- | myisam/mi_check.c | 6 | ||||
-rw-r--r-- | myisam/mi_test1.c | 279 | ||||
-rw-r--r-- | myisam/mi_write.c | 16 | ||||
-rw-r--r-- | myisam/myisamchk.c | 51 | ||||
-rw-r--r-- | myisam/myisampack.c | 178 | ||||
-rw-r--r-- | myisam/sort.c | 2 |
14 files changed, 655 insertions, 443 deletions
diff --git a/myisam/ft_boolean_search.c b/myisam/ft_boolean_search.c index 0c5efcb50df..f2f3a806892 100644 --- a/myisam/ft_boolean_search.c +++ b/myisam/ft_boolean_search.c @@ -59,6 +59,7 @@ static double *nwghts=_nwghts+5; /* nwghts[i] = -0.5*1.5**i */ typedef struct st_ftb_expr FTB_EXPR; struct st_ftb_expr { FTB_EXPR *up; + byte *quot, *qend; float weight; uint flags; my_off_t docid[2]; /* for index search and for scan */ @@ -76,7 +77,7 @@ typedef struct st_ftb_word { my_off_t docid[2]; /* for index search and for scan */ uint ndepth; int len; - /* ... there can be docid cache added here. SerG */ + /* ... docid cache can be added here. SerG */ byte word[1]; } FTB_WORD; @@ -84,10 +85,12 @@ typedef struct st_ft_info { struct _ft_vft *please; MI_INFO *info; uint keynr; + CHARSET_INFO *charset; enum { UNINITIALIZED, READY, INDEX_SEARCH, INDEX_DONE /*, SCAN*/ } state; uint with_scan; FTB_EXPR *root; QUEUE queue; + TREE no_dupes; FTB_WORD **list; MEM_ROOT mem_root; } FTB; @@ -101,18 +104,18 @@ int FTB_WORD_cmp(void *v __attribute__((unused)), FTB_WORD *a, FTB_WORD *b) return i; } -int FTB_WORD_cmp_list(void *v __attribute__((unused)), FTB_WORD **a, FTB_WORD **b) +int FTB_WORD_cmp_list(CHARSET_INFO *cs, FTB_WORD **a, FTB_WORD **b) { /* ORDER BY word DESC, ndepth DESC */ - int i= mi_compare_text(default_charset_info, (*b)->word+1,(*b)->len-1, - (*a)->word+1,(*a)->len-1,0); + int i= mi_compare_text(cs, (*b)->word+1,(*b)->len-1, + (*a)->word+1,(*a)->len-1,0); if (!i) i=CMP_NUM((*b)->ndepth,(*a)->ndepth); return i; } void _ftb_parse_query(FTB *ftb, byte **start, byte *end, - FTB_EXPR *up, uint depth) + FTB_EXPR *up, uint depth) { byte res; FTB_PARAM param; @@ -125,16 +128,17 @@ void _ftb_parse_query(FTB *ftb, byte **start, byte *end, return; param.prev=' '; + param.quot=up->quot; while ((res=ft_get_word(start,end,&w,¶m))) { - int r=param.plusminus; + int r=param.plusminus; float weight= (float) (param.pmsign ? nwghts : wghts)[(r>5)?5:((r<-5)?-5:r)]; switch (res) { case 1: /* word found */ ftbw=(FTB_WORD *)alloc_root(&ftb->mem_root, - sizeof(FTB_WORD) + - (param.trunc ? MI_MAX_KEY_BUFF : - w.len+extra)); + sizeof(FTB_WORD) + + (param.trunc ? MI_MAX_KEY_BUFF : + w.len+extra)); ftbw->len=w.len+1; ftbw->flags=0; if (param.yesno>0) ftbw->flags|=FTB_FLAG_YES; @@ -148,7 +152,7 @@ void _ftb_parse_query(FTB *ftb, byte **start, byte *end, ftbw->word[0]=w.len; if (param.yesno > 0) up->ythresh++; queue_insert(& ftb->queue, (byte *)ftbw); - ftb->with_scan|=param.trunc; + ftb->with_scan|=(param.trunc & FTB_FLAG_TRUNC); break; case 2: /* left bracket */ ftbe=(FTB_EXPR *)alloc_root(&ftb->mem_root, sizeof(FTB_EXPR)); @@ -159,17 +163,25 @@ void _ftb_parse_query(FTB *ftb, byte **start, byte *end, ftbe->up=up; ftbe->ythresh=ftbe->yweaks=0; ftbe->docid[0]=ftbe->docid[1]=HA_POS_ERROR; + if ((ftbe->quot=param.quot)) ftb->with_scan|=2; if (param.yesno > 0) up->ythresh++; _ftb_parse_query(ftb, start, end, ftbe, depth+1); + param.quot=0; break; case 3: /* right bracket */ + if (up->quot) up->qend=param.quot; return; } } return; } -void _ftb_init_index_search(FT_INFO *ftb) +static int _ftb_no_dupes_cmp(void* not_used, const void *a,const void *b) +{ + return CMP_NUM((*((my_off_t*)a)), (*((my_off_t*)b))); +} + +void _ftb_init_index_search(FT_INFO *ftb) { int i, r; FTB_WORD *ftbw; @@ -188,27 +200,48 @@ void _ftb_init_index_search(FT_INFO *ftb) { ftbw=(FTB_WORD *)(ftb->queue.root[i]); - if (ftbw->flags&FTB_FLAG_TRUNC && - (ftbw->up->ythresh > test(ftbw->flags&FTB_FLAG_YES))) - { - /* no need to search for this prefix in the index - - * it cannot ADD new matches, and to REMOVE half-matched - * rows we do scan anyway */ - ftbw->docid[0]=HA_POS_ERROR; - ftbw->up->yweaks++; - continue; - } + if (ftbw->flags&FTB_FLAG_TRUNC) + /* special treatment for truncation operator :(( + 1. +trunc* and there're other (not +trunc*) words + | no need to search in the index, it can never ADD new rows + | to the result, and to remove half-matched rows we do scan anyway + 2. -trunc* + | same as 1. + 3. trunc* + | We have to index-search for this prefix. + | It may cause duplicates, as in the index (sorted by <word,docid>) + | <aaaa,row1> + | <aabb,row2> + | <aacc,row1> + | Searching for "aa*" will find row1 twice... + */ + if ( test(ftbw->flags&FTB_FLAG_NO) || /* 2 */ + (test(ftbw->flags&FTB_FLAG_YES) && /* 1 */ + ftbw->up->ythresh - ftbw->up->yweaks >1)) /* 1 */ + { + ftbw->docid[0]=HA_POS_ERROR; + ftbw->up->yweaks++; + continue; + } + else /* 3 */ + { + if (!is_tree_inited(& ftb->no_dupes)) + { + init_tree(& ftb->no_dupes,0,0,sizeof(my_off_t), + _ftb_no_dupes_cmp,0,0,0); + } + } r=_mi_search(info, keyinfo, (uchar*) ftbw->word, ftbw->len, SEARCH_FIND | SEARCH_BIGGER, keyroot); if (!r) { - r= mi_compare_text(default_charset_info, + r= mi_compare_text(ftb->charset, info->lastkey + (ftbw->flags&FTB_FLAG_TRUNC), ftbw->len - (ftbw->flags&FTB_FLAG_TRUNC), ftbw->word + (ftbw->flags&FTB_FLAG_TRUNC), ftbw->len - (ftbw->flags&FTB_FLAG_TRUNC), - 0); + 0); } if (r) /* not found */ { @@ -241,14 +274,18 @@ FT_INFO * ft_init_boolean_search(MI_INFO *info, uint keynr, byte *query, ftb->state=UNINITIALIZED; ftb->info=info; ftb->keynr=keynr; + ftb->charset= ((keynr==NO_SUCH_KEY) ? + default_charset_info : + info->s->keyinfo[keynr].seg->charset); ftb->with_scan=0; + bzero(& ftb->no_dupes, sizeof(TREE)); init_alloc_root(&ftb->mem_root, 1024, 1024); /* hack: instead of init_queue, we'll use reinit queue to be able * to alloc queue with alloc_root() */ - res=ftb->queue.max_elements=query_len/(ft_min_word_len+1); + res=ftb->queue.max_elements=1+query_len/(ft_min_word_len+1); ftb->queue.root=(byte **)alloc_root(&ftb->mem_root, (res+1)*sizeof(void*)); reinit_queue(& ftb->queue, res, 0, 0, (int (*)(void*,byte*,byte*))FTB_WORD_cmp, ftb); @@ -256,6 +293,7 @@ FT_INFO * ft_init_boolean_search(MI_INFO *info, uint keynr, byte *query, ftbe->weight=1; ftbe->flags=FTB_FLAG_YES; ftbe->nos=1; + ftbe->quot=0; ftbe->up=0; ftbe->ythresh=ftbe->yweaks=0; ftbe->docid[0]=ftbe->docid[1]=HA_POS_ERROR; @@ -263,19 +301,44 @@ FT_INFO * ft_init_boolean_search(MI_INFO *info, uint keynr, byte *query, _ftb_parse_query(ftb, &query, query+query_len, ftbe, 0); ftb->list=(FTB_WORD **)alloc_root(&ftb->mem_root, sizeof(FTB_WORD *)*ftb->queue.elements); - memcpy(ftb->list, ftb->queue.root, sizeof(FTB_WORD *)*ftb->queue.elements); + memcpy(ftb->list, ftb->queue.root+1, sizeof(FTB_WORD *)*ftb->queue.elements); qsort2(ftb->list, ftb->queue.elements, sizeof(FTB_WORD *), - (qsort2_cmp)FTB_WORD_cmp_list, 0); - if (ftb->queue.elements<2) ftb->with_scan=0; + (qsort2_cmp)FTB_WORD_cmp_list, ftb->charset); + if (ftb->queue.elements<2) ftb->with_scan &= ~FTB_FLAG_TRUNC; ftb->state=READY; return ftb; } -void _ftb_climb_the_tree(FTB_WORD *ftbw, uint mode) +/* returns 1 if str0 contain str1 */ +int _ftb_strstr(const byte *s0, const byte *e0, + const byte *s1, const byte *e1, + CHARSET_INFO *cs) { + const byte *p; + + while (s0 < e0) + { + while (s0 < e0 && cs->to_upper[(uint) (uchar) *s0++] != + cs->to_upper[(uint) (uchar) *s1]) + /* no-op */; + if (s0 >= e0) + return 0; + p=s1+1; + while (s0 < e0 && p < e1 && cs->to_upper[(uint) (uchar) *s0++] == + cs->to_upper[(uint) (uchar) *p++]) + /* no-op */; + if (p >= e1) + return 1; + } + return 0; +} + +void _ftb_climb_the_tree(FTB *ftb, FTB_WORD *ftbw, FT_SEG_ITERATOR *ftsi_orig) +{ + FT_SEG_ITERATOR ftsi; FTB_EXPR *ftbe; float weight=ftbw->weight; - int yn=ftbw->flags, ythresh; + int yn=ftbw->flags, ythresh, mode=(ftsi_orig != 0); my_off_t curdoc=ftbw->docid[mode]; for (ftbe=ftbw->up; ftbe; ftbe=ftbe->up) @@ -291,11 +354,26 @@ void _ftb_climb_the_tree(FTB_WORD *ftbw, uint mode) break; if (yn & FTB_FLAG_YES) { - ftbe->cur_weight+=weight; + weight /= ftbe->ythresh; + ftbe->cur_weight += weight; if (++ftbe->yesses == ythresh) { yn=ftbe->flags; weight=ftbe->cur_weight*ftbe->weight; + if (mode && ftbe->quot) + { + int not_found=1; + + memcpy(&ftsi, ftsi_orig, sizeof(ftsi)); + while (_mi_ft_segiterator(&ftsi) && not_found) + { + if (!ftsi.pos) + continue; + not_found = ! _ftb_strstr(ftsi.pos, ftsi.pos+ftsi.len, + ftbe->quot, ftbe->qend, ftb->charset); + } + if (not_found) break; + } /* ftbe->quot */ } else break; @@ -315,7 +393,8 @@ void _ftb_climb_the_tree(FTB_WORD *ftbw, uint mode) } else { - ftbe->cur_weight+=weight; + if (ftbe->ythresh) weight/=3; + ftbe->cur_weight += weight; if (ftbe->yesses < ythresh) break; yn= (ftbe->yesses++ == ythresh) ? ftbe->flags : 0 ; @@ -352,18 +431,18 @@ int ft_boolean_read_next(FT_INFO *ftb, char *record) { while (curdoc==(ftbw=(FTB_WORD *)queue_top(& ftb->queue))->docid[0]) { - _ftb_climb_the_tree(ftbw,0); + _ftb_climb_the_tree(ftb, ftbw, 0); /* update queue */ r=_mi_search(info, keyinfo, (uchar*) ftbw->word, USE_WHOLE_KEY, SEARCH_BIGGER , keyroot); if (!r) { - r= mi_compare_text(default_charset_info, + r= mi_compare_text(ftb->charset, info->lastkey + (ftbw->flags&FTB_FLAG_TRUNC), ftbw->len - (ftbw->flags&FTB_FLAG_TRUNC), ftbw->word + (ftbw->flags&FTB_FLAG_TRUNC), - ftbw->len - (ftbw->flags&FTB_FLAG_TRUNC), + ftbw->len - (ftbw->flags&FTB_FLAG_TRUNC), 0); } if (r) /* not found */ @@ -388,6 +467,11 @@ int ft_boolean_read_next(FT_INFO *ftb, char *record) ftbe->yesses>=(ftbe->ythresh-ftbe->yweaks) && !ftbe->nos) { /* curdoc matched ! */ + if (is_tree_inited(& ftb->no_dupes) && + tree_insert(& ftb->no_dupes, &curdoc, 0)->count >1) + /* but it managed to get past this line once */ + continue; + info->lastpos=curdoc; info->update&= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED); /* why is this ? */ @@ -410,7 +494,7 @@ float ft_boolean_find_relevance(FT_INFO *ftb, byte *record, uint length) FT_WORD word; FTB_WORD *ftbw; FTB_EXPR *ftbe; - FT_SEG_ITERATOR ftsi; + FT_SEG_ITERATOR ftsi, ftsi2; const byte *end; my_off_t docid=ftb->info->lastpos; @@ -419,17 +503,11 @@ float ft_boolean_find_relevance(FT_INFO *ftb, byte *record, uint length) if (!ftb->queue.elements) return 0; -#if NOT_USED - if (ftb->state == READY || ftb->state == INDEX_DONE) - ftb->state=SCAN; - else if (ftb->state != SCAN) - return -3.0; -#endif - if (ftb->keynr==NO_SUCH_KEY) _mi_ft_segiterator_dummy_init(record, length, &ftsi); else _mi_ft_segiterator_init(ftb->info, ftb->keynr, record, &ftsi); + memcpy(&ftsi2, &ftsi, sizeof(ftsi)); while (_mi_ft_segiterator(&ftsi)) { @@ -437,15 +515,15 @@ float ft_boolean_find_relevance(FT_INFO *ftb, byte *record, uint length) continue; end=ftsi.pos+ftsi.len; - while (ft_simple_get_word((byte **)&ftsi.pos,(byte *)end,&word)) + while (ft_simple_get_word((byte **) &ftsi.pos,(byte *) end, &word)) { int a, b, c; for (a=0, b=ftb->queue.elements, c=(a+b)/2; b-a>1; c=(a+b)/2) { ftbw=(FTB_WORD *)(ftb->list[c]); - if (mi_compare_text(default_charset_info, word.pos,word.len, - (uchar*) ftbw->word+1,ftbw->len-1, - (ftbw->flags&FTB_FLAG_TRUNC) ) >0) + if (mi_compare_text(ftb->charset, word.pos, word.len, + (uchar*) ftbw->word+1, ftbw->len-1, + (my_bool) (ftbw->flags&FTB_FLAG_TRUNC)) >0) b=c; else a=c; @@ -453,14 +531,14 @@ float ft_boolean_find_relevance(FT_INFO *ftb, byte *record, uint length) for (; c>=0; c--) { ftbw=(FTB_WORD *)(ftb->list[c]); - if (mi_compare_text(default_charset_info, word.pos,word.len, - (uchar*) ftbw->word+1,ftbw->len-1, - (ftbw->flags&FTB_FLAG_TRUNC) )) + if (mi_compare_text(ftb->charset, word.pos,word.len, + (uchar*) ftbw->word+1,ftbw->len-1, + (my_bool) (ftbw->flags&FTB_FLAG_TRUNC))) break; if (ftbw->docid[1] == docid) continue; ftbw->docid[1]=docid; - _ftb_climb_the_tree(ftbw,1); + _ftb_climb_the_tree(ftb, ftbw, &ftsi2); } } } @@ -479,6 +557,10 @@ float ft_boolean_find_relevance(FT_INFO *ftb, byte *record, uint length) void ft_boolean_close_search(FT_INFO *ftb) { + if (is_tree_inited(& ftb->no_dupes)) + { + delete_tree(& ftb->no_dupes); + } free_root(& ftb->mem_root, MYF(0)); my_free((gptr)ftb,MYF(0)); } diff --git a/myisam/ft_dump.c b/myisam/ft_dump.c index c40145b87ed..25de17d5db4 100644 --- a/myisam/ft_dump.c +++ b/myisam/ft_dump.c @@ -14,22 +14,46 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -/* Written by Sergei A. Golubchik, who has a shared copyright to this code */ +/* Written by Sergei A. Golubchik, who has a shared copyright to this code + added support for long options (my_getopt) 22.5.2002 by Jani Tolonen */ #include "ftdefs.h" -#include <getopt.h> +#include <my_getopt.h> static void get_options(int argc,char *argv[]); -static void usage(char *argv[]); +static void usage(); static void complain(int val); -static int count=0, stats=0, dump=0, verbose=0, lstats=0; +static int count=0, stats=0, dump=0, lstats=0; +static my_bool verbose; static char *query=NULL; static uint lengths[256]; #define MAX_LEN (HA_FT_MAXLEN+10) #define HOW_OFTEN_TO_WRITE 10000 +static struct my_option my_long_options[] = +{ + {"dump", 'd', "Dump index (incl. data offsets and word weights)", + 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"stats", 's', "Report global stats", + 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"verbose", 'v', "Be verbose", + (gptr*) &verbose, (gptr*) &verbose, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"count", 'c', "Calculate per-word stats (counts and global weights)", + 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"length", 'l', "Report length distribution", + 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"execute", 'e', "Execute given query", (gptr*) &query, (gptr*) &query, 0, + GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"help", 'h', "Display help and exit", + 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"help", '?', "Synonym for -h", + 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} +}; + + int main(int argc,char *argv[]) { int error=0; @@ -52,7 +76,7 @@ int main(int argc,char *argv[]) setbuf(stdout,NULL); if (argc-optind < 2) - usage(argv); + usage(); if (!(info=mi_open(argv[optind],2,HA_OPEN_ABORT_IF_LOCKED))) goto err; @@ -184,45 +208,56 @@ err: return 0; } -const char *options="dslcvh"; + +static my_bool +get_one_option(int optid, const struct my_option *opt __attribute__((unused)), + char *argument __attribute__((unused))) +{ + switch(optid) { + case 'd': + dump=1; + complain(count || query); + break; + case 's': + stats=1; + complain(query!=0); + break; + case 'c': + count= 1; + complain(dump || query); + break; + case 'l': + lstats=1; + complain(query!=0); + break; + case 'e': + complain(dump || count || stats); + break; + case '?': + case 'h': + usage(); + } + return 0; +} static void get_options(int argc, char *argv[]) { - int c; + int ho_error; - while ((c=getopt(argc,argv,options)) != -1) - { - switch(c) { - case 'd': dump=1; complain(count || query); break; - case 's': stats=1; complain(query!=0); break; - case 'v': verbose=1; break; - case 'c': count=1; complain(dump || query); break; - case 'l': lstats=1; complain(query!=0); break; - case 'e': query=my_strdup(optarg,MYF(MY_FAE)); complain(dump || count || stats); break; - case '?': - case 'h': - default: - usage(argv); - } - } - return; + if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option))) + exit(ho_error); } /* get options */ -static void usage(char *argv[]) + +static void usage() { - printf("\n\ -Use: %s [-%s] <table_name> <index_no>\n\ -\n\ --d Dump index (incl. data offsets and word weights)\n\ --s Report global stats\n\ --c Calculate per-word stats (counts and global weights)\n\ --l Report length distribution\n\ --v Be verbose\n\ --h This text\n\ -", *argv, options); + printf("Use: ft_dump <table_name> <index_no>\n"); + my_print_help(my_long_options); + my_print_variables(my_long_options); exit(1); } + static void complain(int val) /* Kinda assert :-) */ { if (val) diff --git a/myisam/ft_eval.c b/myisam/ft_eval.c index c498725daab..e196121d7af 100644 --- a/myisam/ft_eval.c +++ b/myisam/ft_eval.c @@ -11,18 +11,32 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -/* Written by Sergei A. Golubchik, who has a shared copyright to this code */ +/* Written by Sergei A. Golubchik, who has a shared copyright to this code + added support for long options (my_getopt) 22.5.2002 by Jani Tolonen */ #include "ftdefs.h" #include "ft_eval.h" #include <stdarg.h> -#include <getopt.h> +#include <my_getopt.h> static void print_error(int exit_code, const char *fmt,...); static void get_options(int argc, char *argv[]); static int create_record(char *pos, FILE *file); +static void usage(); -int main(int argc,char *argv[]) +static struct my_option my_long_options[] = +{ + {"", 's', "", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"", 'q', "", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"", 'S', "", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"", '#', "", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"", 'V', "", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"", '?', "", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"", 'h', "", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} +}; + +int main(int argc, char *argv[]) { MI_INFO *file; int i,j; @@ -81,7 +95,9 @@ int main(int argc,char *argv[]) if (!silent) printf("- Reading rows with key\n"); for(i=1;create_record(record,qf);i++) { - FT_DOCLIST *result; double w; int t,err; + FT_DOCLIST *result; + double w; + int t, err; result=ft_nlq_init_search(file,0,blob_record,(uint) strlen(blob_record),1); if(!result) { @@ -94,7 +110,7 @@ int main(int argc,char *argv[]) t=uint2korr(read_record); w=ft_nlq_get_relevance(result); printf("%d %.*s %f\n",i,t,read_record+2,w); - } + } if(err != HA_ERR_END_OF_FILE) { printf("ft_read_next %d failed with errno %3d\n",j,my_errno); goto err; @@ -106,58 +122,65 @@ int main(int argc,char *argv[]) my_end(MY_CHECK_ERROR); return (0); -err: + + err: printf("got error: %3d when using myisam-database\n",my_errno); - return 1; /* skipp warning */ + return 1; /* skip warning */ } -static void get_options(int argc,char *argv[]) -{ - int c; - char *options=(char*) "Vh#:qSs:"; - while ((c=getopt(argc,argv,options)) != -1) - { - switch(c) { - case 's': - if(stopwordlist && stopwordlist!=ft_precompiled_stopwords) break; - { - FILE *f; char s[HA_FT_MAXLEN]; int i=0,n=SWL_INIT; - - if(!(stopwordlist=(const char**) malloc(n*sizeof(char *)))) - print_error(1,"malloc(%d)",n*sizeof(char *)); - if(!(f=fopen(optarg,"r"))) - print_error(1,"fopen(%s)",optarg); - while(!feof(f)) { - if(!(fgets(s,HA_FT_MAXLEN,f))) - print_error(1,"fgets(s,%d,%s)",HA_FT_MAXLEN,optarg); - if(!(stopwordlist[i++]=strdup(s))) - print_error(1,"strdup(%s)",s); - if(i>=n) { - n+=SWL_PLUS; - if(!(stopwordlist=(const char**) realloc((char*) stopwordlist,n*sizeof(char *)))) - print_error(1,"realloc(%d)",n*sizeof(char *)); - } +static my_bool +get_one_option(int optid, const struct my_option *opt __attribute__((unused)), + char *argument) +{ + switch(optid) { + case 's': + if(stopwordlist && stopwordlist!=ft_precompiled_stopwords) break; + { + FILE *f; char s[HA_FT_MAXLEN]; int i=0,n=SWL_INIT; + + if(!(stopwordlist=(const char**) malloc(n*sizeof(char *)))) + print_error(1,"malloc(%d)",n*sizeof(char *)); + if(!(f=fopen(argument,"r"))) + print_error(1,"fopen(%s)",argument); + while(!feof(f)) { + if(!(fgets(s,HA_FT_MAXLEN,f))) + print_error(1,"fgets(s,%d,%s)",HA_FT_MAXLEN,argument); + if(!(stopwordlist[i++]=strdup(s))) + print_error(1,"strdup(%s)",s); + if(i>=n) { + n+=SWL_PLUS; + if(!(stopwordlist=(const char**) realloc((char*) stopwordlist,n*sizeof(char *)))) + print_error(1,"realloc(%d)",n*sizeof(char *)); } - fclose(f); - stopwordlist[i]=NULL; - break; } - case 'q': silent=1; break; - case 'S': if(stopwordlist==ft_precompiled_stopwords) stopwordlist=NULL; break; - case '#': - DEBUGGER_ON; - DBUG_PUSH (optarg); + fclose(f); + stopwordlist[i]=NULL; break; - case 'V': - case '?': - case 'h': - default: - printf("%s -[%s] <d_file> <q_file>\n", argv[0], options); - exit(0); } + case 'q': silent=1; break; + case 'S': if(stopwordlist==ft_precompiled_stopwords) stopwordlist=NULL; break; + case '#': + DEBUGGER_ON; + DBUG_PUSH (argument); + break; + case 'V': + case '?': + case 'h': + usage(); + exit(1); } + return 0; +} + +static void get_options(int argc, char *argv[]) +{ + int ho_error; + + if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option))) + exit(ho_error); + if(!(d_file=argv[optind])) print_error(1,"No d_file"); if(!(df=fopen(d_file,"r"))) print_error(1,"fopen(%s)",d_file); @@ -206,3 +229,11 @@ static void print_error(int exit_code, const char *fmt,...) va_end(args); exit(exit_code); } + + +static void usage() +{ + printf("%s [options]\n", my_progname); + my_print_help(my_long_options); + my_print_variables(my_long_options); +} diff --git a/myisam/ft_nlq_search.c b/myisam/ft_nlq_search.c index 5b12c4d4571..d9730110677 100644 --- a/myisam/ft_nlq_search.c +++ b/myisam/ft_nlq_search.c @@ -37,6 +37,7 @@ struct st_ft_info { typedef struct st_all_in_one { MI_INFO *info; uint keynr; + CHARSET_INFO *charset; uchar *keybuff; MI_KEYDEF *keyinfo; my_off_t key_root; @@ -93,9 +94,10 @@ static int walk_and_match(FT_WORD *word, uint32 count, ALL_IN_ONE *aio) while(!r) { - if (mi_compare_text(default_charset_info, + if (mi_compare_text(aio->charset, aio->info->lastkey,keylen, - aio->keybuff,keylen,0)) break; + aio->keybuff,keylen,0)) + break; #if HA_FT_WTYPE == HA_KEYTYPE_FLOAT #ifdef EVAL_RUN @@ -184,8 +186,9 @@ FT_INFO *ft_init_nlq_search(MI_INFO *info, uint keynr, byte *query, aio.info=info; aio.keynr=keynr; - aio.keybuff=info->lastkey+info->s->base.max_key_length; aio.keyinfo=info->s->keyinfo+keynr; + aio.charset=aio.keyinfo->seg->charset; + aio.keybuff=info->lastkey+info->s->base.max_key_length; aio.key_root=info->s->state.key_root[keynr]; bzero(&allocated_wtree,sizeof(allocated_wtree)); @@ -193,6 +196,7 @@ FT_INFO *ft_init_nlq_search(MI_INFO *info, uint keynr, byte *query, init_tree(&aio.dtree,0,0,sizeof(FT_SUPERDOC),(qsort_cmp2)&FT_SUPERDOC_cmp,0, NULL, NULL); + ft_parse_init(&allocated_wtree, aio.charset); if(ft_parse(&allocated_wtree,query,query_len)) goto err; diff --git a/myisam/ft_parser.c b/myisam/ft_parser.c index 93c574841f7..15a17ed6f3b 100644 --- a/myisam/ft_parser.c +++ b/myisam/ft_parser.c @@ -35,12 +35,10 @@ typedef struct st_ft_docstat { } FT_DOCSTAT; -static int FT_WORD_cmp(void* cmp_arg, FT_WORD *w1, FT_WORD *w2) +static int FT_WORD_cmp(CHARSET_INFO* cs, FT_WORD *w1, FT_WORD *w2) { - return mi_compare_text(default_charset_info, - (uchar*) w1->pos, w1->len, - (uchar*) w2->pos, w2->len, - (my_bool) (cmp_arg != 0)); + return mi_compare_text(cs, (uchar*) w1->pos, w1->len, + (uchar*) w2->pos, w2->len, 0); } static int walk_and_copy(FT_WORD *word,uint32 count,FT_DOCSTAT *docstat) @@ -139,13 +137,20 @@ byte ft_get_word(byte **start, byte *end, FT_WORD *word, FTB_PARAM *param) default_charset_info correctly */ if (true_word_char(default_charset_info,*doc)) break; - if (*doc == FTB_LBR || *doc == FTB_RBR) + if (*doc == FTB_RQUOT && param->quot) { + param->quot=doc; + *start=doc+1; + return 3; /* FTB_RBR */ + } + if ((*doc == FTB_LBR || *doc == FTB_RBR || *doc == FTB_LQUOT) + && !param->quot) { /* param->prev=' '; */ *start=doc+1; + if (*doc == FTB_LQUOT) param->quot=*start; return (*doc == FTB_RBR)+2; } - if (param->prev == ' ') + if (param->prev == ' ' && !param->quot) { if (*doc == FTB_YES ) { param->yesno=+1; continue; } else if (*doc == FTB_EGAL) { param->yesno= 0; continue; } else @@ -155,7 +160,8 @@ byte ft_get_word(byte **start, byte *end, FT_WORD *word, FTB_PARAM *param) if (*doc == FTB_NEG ) { param->pmsign=!param->pmsign; continue; } } param->prev=*doc; - param->yesno=param->plusminus=param->pmsign=0; + param->yesno=(param->quot != 0); + param->plusminus=param->pmsign=0; } mwc=0; @@ -211,16 +217,17 @@ byte ft_simple_get_word(byte **start, byte *end, FT_WORD *word) return 0; } +void ft_parse_init(TREE *wtree, CHARSET_INFO *cs) +{ + if (!is_tree_inited(wtree)) + init_tree(wtree,0,0,sizeof(FT_WORD),(qsort_cmp2)&FT_WORD_cmp,0,NULL, cs); +} + int ft_parse(TREE *wtree, byte *doc, int doclen) { byte *end=doc+doclen; FT_WORD w; - if (!is_tree_inited(wtree)) - { - init_tree(wtree,0,0,sizeof(FT_WORD),(qsort_cmp2)&FT_WORD_cmp,0,NULL, NULL); - } - while (ft_simple_get_word(&doc,end,&w)) { if (!tree_insert(wtree, &w, 0, wtree->custom_arg)) diff --git a/myisam/ft_test1.c b/myisam/ft_test1.c index caa41d4a8c5..6b2493918ff 100644 --- a/myisam/ft_test1.c +++ b/myisam/ft_test1.c @@ -14,11 +14,12 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -/* Written by Sergei A. Golubchik, who has a shared copyright to this code */ +/* Written by Sergei A. Golubchik, who has a shared copyright to this code + added support for long options (my_getopt) 22.5.2002 by Jani Tolonen */ #include "ftdefs.h" #include "ft_test1.h" -#include <getopt.h> +#include <my_getopt.h> static int key_field=FIELD_VARCHAR,extra_field=FIELD_SKIP_ENDSPACE; static uint key_length=200,extra_length=50; @@ -33,8 +34,26 @@ static char record[MAX_REC_LENGTH],read_record[MAX_REC_LENGTH]; static int run_test(const char *filename); static void get_options(int argc, char *argv[]); static void create_record(char *, int); +static void usage(); -int main(int argc,char *argv[]) +static struct my_option my_long_options[] = +{ + {"", 'v', "", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"", '?', "", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"", 'h', "", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"", 'V', "", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"", 'v', "", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"", 's', "", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"", 'N', "", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"", 'S', "", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"", 'K', "", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"", 'F', "", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"", 'U', "", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"", '#', "", 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, + { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} +}; + +int main(int argc, char *argv[]) { MY_INIT(argv[0]); @@ -173,7 +192,7 @@ static int run_test(const char *filename) return (0); err: printf("got error: %3d when using myisam-database\n",my_errno); - return 1; /* skipp warning */ + return 1; /* skip warning */ } static char blob_key[MAX_REC_LENGTH]; @@ -232,34 +251,47 @@ void create_record(char *pos, int n) } } + +static my_bool +get_one_option(int optid, const struct my_option *opt __attribute__((unused)), + char *argument) +{ + switch(optid) { + case 'v': verbose=1; break; + case 's': silent=1; break; + case 'F': no_fulltext=1; no_search=1; + case 'U': skip_update=1; break; + case 'K': no_keys=no_search=1; break; + case 'N': no_search=1; break; + case 'S': no_stopwords=1; break; + case '#': + DEBUGGER_ON; + DBUG_PUSH (argument); + break; + case 'V': + case '?': + case 'h': + usage(); + exit(1); + } + return 0; +} + /* Read options */ static void get_options(int argc,char *argv[]) { - int c; - const char *options="hVvsNSKFU#:"; + int ho_error; - while ((c=getopt(argc,argv,options)) != -1) - { - switch(c) { - case 'v': verbose=1; break; - case 's': silent=1; break; - case 'F': no_fulltext=1; no_search=1; - case 'U': skip_update=1; break; - case 'K': no_keys=no_search=1; break; - case 'N': no_search=1; break; - case 'S': no_stopwords=1; break; - case '#': - DEBUGGER_ON; - DBUG_PUSH (optarg); - break; - case 'V': - case '?': - case 'h': - default: - printf("%s -[%s]\n", argv[0], options); - exit(0); - } - } + if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option))) + exit(ho_error); return; } /* get options */ + + +static void usage() +{ + printf("%s [options]\n", my_progname); + my_print_help(my_long_options); + my_print_variables(my_long_options); +} diff --git a/myisam/ft_update.c b/myisam/ft_update.c index 04b6becde86..3c9b31207c0 100644 --- a/myisam/ft_update.c +++ b/myisam/ft_update.c @@ -90,16 +90,13 @@ uint _mi_ft_parse(TREE *parsed, MI_INFO *info, uint keynr, const byte *record) FT_SEG_ITERATOR ftsi; _mi_ft_segiterator_init(info, keynr, record, &ftsi); + ft_parse_init(parsed, info->s->keyinfo[keynr].seg->charset); while (_mi_ft_segiterator(&ftsi)) if (ftsi.pos) if (ft_parse(parsed, (byte *)ftsi.pos, ftsi.len)) return 1; - /* Handle the case where all columns are NULL */ - if (!is_tree_inited(parsed) && ft_parse(parsed, (byte*) "", 0)) - return 1; - else - return 0; + return 0; } FT_WORD * _mi_ft_parserecord(MI_INFO *info, uint keynr, @@ -153,6 +150,7 @@ static int _mi_ft_erase(MI_INFO *info, uint keynr, byte *keybuf, FT_WORD *wlist, int _mi_ft_cmp(MI_INFO *info, uint keynr, const byte *rec1, const byte *rec2) { FT_SEG_ITERATOR ftsi1, ftsi2; + CHARSET_INFO *cs=info->s->keyinfo[keynr].seg->charset; _mi_ft_segiterator_init(info, keynr, rec1, &ftsi1); _mi_ft_segiterator_init(info, keynr, rec2, &ftsi2); @@ -160,9 +158,8 @@ int _mi_ft_cmp(MI_INFO *info, uint keynr, const byte *rec1, const byte *rec2) { if ((ftsi1.pos != ftsi2.pos) && (!ftsi1.pos || !ftsi2.pos || - mi_compare_text(default_charset_info, - (uchar*) ftsi1.pos,ftsi1.len, - (uchar*) ftsi2.pos,ftsi2.len,0))) + mi_compare_text(cs, (uchar*) ftsi1.pos,ftsi1.len, + (uchar*) ftsi2.pos,ftsi2.len,0))) return THOSE_TWO_DAMN_KEYS_ARE_REALLY_DIFFERENT; } return GEE_THEY_ARE_ABSOLUTELY_IDENTICAL; @@ -174,6 +171,7 @@ int _mi_ft_update(MI_INFO *info, uint keynr, byte *keybuf, { int error= -1; FT_WORD *oldlist,*newlist, *old_word, *new_word; + CHARSET_INFO *cs=info->s->keyinfo[keynr].seg->charset; uint key_length; int cmp, cmp2; @@ -185,9 +183,8 @@ int _mi_ft_update(MI_INFO *info, uint keynr, byte *keybuf, error=0; while(old_word->pos && new_word->pos) { - cmp= mi_compare_text(default_charset_info, - (uchar*) old_word->pos,old_word->len, - (uchar*) new_word->pos,new_word->len,0); + cmp= mi_compare_text(cs, (uchar*) old_word->pos,old_word->len, + (uchar*) new_word->pos,new_word->len,0); cmp2= cmp ? 0 : (fabs(old_word->weight - new_word->weight) > 1.e-5); if (cmp < 0 || cmp2) diff --git a/myisam/ftdefs.h b/myisam/ftdefs.h index f829a5f0c3a..22a81ca4f9c 100644 --- a/myisam/ftdefs.h +++ b/myisam/ftdefs.h @@ -95,6 +95,8 @@ extern ulong collstat; #define FTB_RBR (ft_boolean_syntax[6]) #define FTB_NEG (ft_boolean_syntax[7]) #define FTB_TRUNC (ft_boolean_syntax[8]) +#define FTB_LQUOT (ft_boolean_syntax[10]) +#define FTB_RQUOT (ft_boolean_syntax[11]) typedef struct st_ft_word { byte * pos; @@ -111,6 +113,7 @@ typedef struct st_ftb_param { int plusminus; bool pmsign; bool trunc; + byte *quot; } FTB_PARAM; int is_stopword(char *word, uint len); @@ -130,8 +133,9 @@ void _mi_ft_segiterator_init(MI_INFO *, uint, const byte *, FT_SEG_ITERATOR *); void _mi_ft_segiterator_dummy_init(const byte *, uint, FT_SEG_ITERATOR *); uint _mi_ft_segiterator(FT_SEG_ITERATOR *); +void ft_parse_init(TREE *, CHARSET_INFO *); int ft_parse(TREE *, byte *, int); -FT_WORD * ft_linearize(/*MI_INFO *, uint, byte *, */TREE *); +FT_WORD * ft_linearize(TREE *); FT_WORD * _mi_ft_parserecord(MI_INFO *, uint, byte *, const byte *); uint _mi_ft_parse(TREE *parsed, MI_INFO *info, uint keynr, const byte *record); diff --git a/myisam/mi_check.c b/myisam/mi_check.c index 9dceccc164f..212659f5828 100644 --- a/myisam/mi_check.c +++ b/myisam/mi_check.c @@ -14,14 +14,14 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -/* Descript, check and repair of ISAM tables */ +/* Descript, check and repair of MyISAM tables */ #include "ftdefs.h" #include <m_ctype.h> #include <stdarg.h> -#include <getopt.h> +#include <my_getopt.h> #include <assert.h> -#ifdef HAVE_SYS_VADVICE_H +#ifdef HAVE_SYS_VADVISE_H #include <sys/vadvise.h> #endif #ifdef HAVE_SYS_MMAN_H diff --git a/myisam/mi_test1.c b/myisam/mi_test1.c index b477263dd4a..88cbbb39663 100644 --- a/myisam/mi_test1.c +++ b/myisam/mi_test1.c @@ -17,20 +17,23 @@ /* Testing of the basic functions of a MyISAM table */ #include "myisam.h" -#include <getopt.h> +#include <my_getopt.h> #include <m_string.h> #define MAX_REC_LENGTH 1024 -static int rec_pointer_size=0,verbose=0,flags[50]; +static void usage(); + +static int rec_pointer_size=0, flags[50]; static int key_field=FIELD_SKIP_PRESPACE,extra_field=FIELD_SKIP_ENDSPACE; static int key_type=HA_KEYTYPE_NUM; static int create_flag=0; -static uint insert_count= 1000,update_count=1000,remove_count=1000; -static uint pack_keys=0,pack_seg=0,null_fields=0,key_length=6,skip_update=0; -static uint unique_key=HA_NOSAME,key_cacheing=0,opt_unique=0; -static uint silent; +static uint insert_count, update_count, remove_count; +static uint pack_keys=0, pack_seg=0, key_length; +static uint unique_key=HA_NOSAME; +static my_bool key_cacheing, null_fields, silent, skip_update, opt_unique, + verbose; static MI_COLUMNDEF recinfo[4]; static MI_KEYDEF keyinfo[10]; static HA_KEYSEG keyseg[10]; @@ -502,139 +505,155 @@ static void update_record(char *record) } -static struct option long_options[] = +static struct my_option my_long_options[] = { - {"checksum", no_argument, 0, 'c'}, + {"checksum", 'c', "Undocumented", + 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, #ifndef DBUG_OFF - {"debug", required_argument, 0, '#'}, + {"debug", '#', "Undocumented", + 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, #endif - {"delete_rows", required_argument, 0, 'd'}, - {"help", no_argument, 0, '?'}, - {"insert_rows", required_argument, 0, 'i'}, - {"key_alpha", no_argument, 0, 'a'}, - {"key_binary_pack", no_argument, 0, 'B'}, - {"key_blob", required_argument, 0, 'b'}, - {"key_cache", no_argument, 0, 'K'}, - {"key_length", required_argument, 0, 'k'}, - {"key_multiple", no_argument, 0, 'm'}, - {"key_prefix_pack", no_argument, 0, 'P'}, - {"key_space_pack", no_argument, 0, 'p'}, - {"key_varchar", no_argument, 0, 'w'}, - {"null_fields", no_argument, 0, 'N'}, - {"row_fixed_size", no_argument, 0, 'S'}, - {"row_pointer_size", required_argument, 0, 'R'}, - {"silent", no_argument, 0, 's'}, - {"skip_update", no_argument, 0, 'U'}, - {"unique", no_argument, 0, 'C'}, - {"update_rows", required_argument, 0, 'u'}, - {"verbose", no_argument, 0, 'v'}, - {"version", no_argument, 0, 'V'}, - {0, 0, 0, 0} + {"delete_rows", 'd', "Undocumented", (gptr*) &remove_count, + (gptr*) &remove_count, 0, GET_UINT, REQUIRED_ARG, 1000, 0, 0, 0, 0, 0}, + {"help", '?', "Display help and exit", + 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"insert_rows", 'i', "Undocumented", (gptr*) &insert_count, + (gptr*) &insert_count, 0, GET_UINT, REQUIRED_ARG, 1000, 0, 0, 0, 0, 0}, + {"key_alpha", 'a', "Undocumented", + 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"key_binary_pack", 'B', "Undocumented", + 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"key_blob", 'b', "Undocumented", + 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"key_cache", 'K', "Undocumented", (gptr*) &key_cacheing, + (gptr*) &key_cacheing, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"key_length", 'k', "Undocumented", (gptr*) &key_length, (gptr*) &key_length, + 0, GET_UINT, REQUIRED_ARG, 6, 0, 0, 0, 0, 0}, + {"key_multiple", 'm', "Undocumented", + 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"key_prefix_pack", 'P', "Undocumented", + 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"key_space_pack", 'p', "Undocumented", + 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"key_varchar", 'w', "Undocumented", + 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"null_fields", 'N', "Undocumented", + (gptr*) &null_fields, (gptr*) &null_fields, 0, GET_BOOL, NO_ARG, + 0, 0, 0, 0, 0, 0}, + {"row_fixed_size", 'S', "Undocumented", + 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"row_pointer_size", 'R', "Undocumented", (gptr*) &rec_pointer_size, + (gptr*) &rec_pointer_size, 0, GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"silent", 's', "Undocumented", + (gptr*) &silent, (gptr*) &silent, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"skip_update", 'U', "Undocumented", (gptr*) &skip_update, + (gptr*) &skip_update, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"unique", 'C', "Undocumented", (gptr*) &opt_unique, (gptr*) &opt_unique, 0, + GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"update_rows", 'u', "Undocumented", (gptr*) &update_count, + (gptr*) &update_count, 0, GET_UINT, REQUIRED_ARG, 1000, 0, 0, 0, 0, 0}, + {"verbose", 'v', "Be more verbose", (gptr*) &verbose, (gptr*) &verbose, 0, + GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"version", 'V', "Print version number and exit", + 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} }; +static my_bool +get_one_option(int optid, const struct my_option *opt __attribute__((unused)), + char *argument) +{ + switch(optid) { + case 'a': + key_type= HA_KEYTYPE_TEXT; + break; + case 'c': + create_flag|= HA_CREATE_CHECKSUM; + break; + case 'R': /* Length of record pointer */ + if (rec_pointer_size > 3) + rec_pointer_size=0; + break; + case 'P': + pack_keys= HA_PACK_KEY; /* Use prefix compression */ + break; + case 'B': + pack_keys= HA_BINARY_PACK_KEY; /* Use binary compression */ + break; + case 'S': + if (key_field == FIELD_VARCHAR) + { + create_flag=0; /* Static sized varchar */ + } + else if (key_field != FIELD_BLOB) + { + key_field=FIELD_NORMAL; /* static-size record */ + extra_field=FIELD_NORMAL; + } + break; + case 'p': + pack_keys=HA_PACK_KEY; /* Use prefix + space packing */ + pack_seg=HA_SPACE_PACK; + key_type=HA_KEYTYPE_TEXT; + break; + case 'm': + unique_key=0; + break; + case 'b': + key_field=FIELD_BLOB; /* blob key */ + extra_field= FIELD_BLOB; + pack_seg|= HA_BLOB_PART; + key_type= HA_KEYTYPE_VARTEXT; + break; + case 'k': + if (key_length < 4 || key_length > MI_MAX_KEY_LENGTH) + { + fprintf(stderr,"Wrong key length\n"); + exit(1); + } + break; + case 'w': + key_field=FIELD_VARCHAR; /* varchar keys */ + extra_field= FIELD_VARCHAR; + key_type= HA_KEYTYPE_VARTEXT; + pack_seg|= HA_VAR_LENGTH; + create_flag|= HA_PACK_RECORD; + break; + case 'K': /* Use key cacheing */ + key_cacheing=1; + break; + case 'V': + printf("test1 Ver 1.2 \n"); + exit(0); + case '#': + DEBUGGER_ON; + DBUG_PUSH (argument); + break; + case '?': + usage(); + exit(1); + } + return 0; +} + + /* Read options */ -static void get_options(int argc,char *argv[]) +static void get_options(int argc, char *argv[]) { - int c,option_index=0; + int ho_error; + + if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option))) + exit(ho_error); - while ((c=getopt_long(argc,argv,"abBcCd:i:k:KmPR:SspNu:UvVw#:", - long_options, &option_index)) != EOF) - { - switch(c) { - case 'a': - key_type= HA_KEYTYPE_TEXT; - break; - case 'c': - create_flag|= HA_CREATE_CHECKSUM; - break; - case 'C': - opt_unique=1; - break; - case 'R': /* Length of record pointer */ - rec_pointer_size=atoi(optarg); - if (rec_pointer_size > 3) - rec_pointer_size=0; - break; - case 'P': - pack_keys= HA_PACK_KEY; /* Use prefix compression */ - break; - case 'B': - pack_keys= HA_BINARY_PACK_KEY; /* Use binary compression */ - break; - case 'S': - if (key_field == FIELD_VARCHAR) - { - create_flag=0; /* Static sized varchar */ - } - else if (key_field != FIELD_BLOB) - { - key_field=FIELD_NORMAL; /* static-size record */ - extra_field=FIELD_NORMAL; - } - break; - case 'p': - pack_keys=HA_PACK_KEY; /* Use prefix + space packing */ - pack_seg=HA_SPACE_PACK; - key_type=HA_KEYTYPE_TEXT; - break; - case 'N': - null_fields=1; /* First key part may be null */ - break; - case 'v': /* verbose */ - verbose=1; - break; - case 'd': - remove_count=atoi(optarg); - break; - case 'i': - insert_count=atoi(optarg); - break; - case 'u': - update_count=atoi(optarg); - break; - case 'U': - skip_update=1; - break; - case 'm': - unique_key=0; - break; - case 'b': - key_field=FIELD_BLOB; /* blob key */ - extra_field= FIELD_BLOB; - pack_seg|= HA_BLOB_PART; - key_type= HA_KEYTYPE_VARTEXT; - break; - case 'k': - key_length=atoi(optarg); - if (key_length < 4 || key_length > MI_MAX_KEY_LENGTH) - { - fprintf(stderr,"Wrong key length\n"); - exit(1); - } - break; - case 's': - silent=1; - break; - case 'w': - key_field=FIELD_VARCHAR; /* varchar keys */ - extra_field= FIELD_VARCHAR; - key_type= HA_KEYTYPE_VARTEXT; - pack_seg|= HA_VAR_LENGTH; - create_flag|= HA_PACK_RECORD; - break; - case 'K': /* Use key cacheing */ - key_cacheing=1; - break; - case 'V': - printf("test1 Ver 1.0 \n"); - exit(0); - case '#': - DEBUGGER_ON; - DBUG_PUSH (optarg); - break; - } - } return; } /* get options */ + + +static void usage() +{ + printf("Usage: %s [options]\n\n", my_progname); + my_print_help(my_long_options); + my_print_variables(my_long_options); +} diff --git a/myisam/mi_write.c b/myisam/mi_write.c index 85bcb8427df..d78a5a1425a 100644 --- a/myisam/mi_write.c +++ b/myisam/mi_write.c @@ -399,7 +399,7 @@ int _mi_insert(register MI_INFO *info, register MI_KEYDEF *keyinfo, { DBUG_PRINT("test",("t_length: %d ref_len: %d", t_length,s_temp.ref_length)); - DBUG_PRINT("test",("n_ref_len: %d n_length: %d key: %lx", + DBUG_PRINT("test",("n_ref_len: %d n_length: %d key_pos: %lx", s_temp.n_ref_length,s_temp.n_length,s_temp.key)); } #endif @@ -761,6 +761,7 @@ int _mi_ck_write_tree(register MI_INFO *info, uint keynr, uchar *key, /* typeof(_mi_keys_compare)=qsort_cmp2 */ + static int keys_compare(bulk_insert_param *param, uchar *key1, uchar *key2) { uint not_used; @@ -810,9 +811,10 @@ int _mi_init_bulk_insert(MI_INFO *info) bulk_insert_param *params; uint i, num_keys; ulonglong key_map=0; + DBUG_ENTER("_mi_init_bulk_insert"); if (info->bulk_insert) - return 0; + DBUG_RETURN(0); for (i=num_keys=0 ; i < share->base.keys ; i++) { @@ -824,15 +826,15 @@ int _mi_init_bulk_insert(MI_INFO *info) } } - if (num_keys==0 || num_keys>myisam_bulk_insert_tree_size) - return 0; + if (num_keys==0 || num_keys > myisam_bulk_insert_tree_size) + DBUG_RETURN(0); info->bulk_insert=(TREE *) my_malloc((sizeof(TREE)*share->base.keys+ sizeof(bulk_insert_param)*num_keys),MYF(0)); if (!info->bulk_insert) - return HA_ERR_OUT_OF_MEM; + DBUG_RETURN(HA_ERR_OUT_OF_MEM); params=(bulk_insert_param *)(info->bulk_insert+share->base.keys); for (i=0 ; i < share->base.keys ; i++,key++) @@ -841,7 +843,7 @@ int _mi_init_bulk_insert(MI_INFO *info) { params->info=info; params->keynr=i; - init_tree(& info->bulk_insert[i], + init_tree(&info->bulk_insert[i], myisam_bulk_insert_tree_size / num_keys / 4 + 10, myisam_bulk_insert_tree_size / num_keys, 0, (qsort_cmp2)keys_compare, 0, @@ -851,5 +853,5 @@ int _mi_init_bulk_insert(MI_INFO *info) info->bulk_insert[i].root=0; } - return 0; + DBUG_RETURN(0); } diff --git a/myisam/myisamchk.c b/myisam/myisamchk.c index 0f290712841..ca0ec824cda 100644 --- a/myisam/myisamchk.c +++ b/myisam/myisamchk.c @@ -155,7 +155,7 @@ static struct my_option my_long_options[] = {"analyze", 'a', "Analyze distribution of keys. Will make some joins in MySQL faster. You can check the calculated distribution.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"block-search", 'b', "No help available.", 0, 0, 0, GET_LONG, REQUIRED_ARG, + {"block-search", 'b', "No help available.", 0, 0, 0, GET_ULONG, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"backup", 'B', "Make a backup of the .MYD file as 'filename-time.BAK'", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, @@ -165,7 +165,7 @@ static struct my_option my_long_options[] = {"check", 'c', "Check table for errors.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, {"check-only-changed", 'C', - "Check only tables that has changed since last check.", 0, 0, 0, GET_NO_ARG, + "Check only tables that have changed since last check.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, {"correct-checksum", OPT_CORRECT_CHECKSUM, "Correct checksum information for table.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, @@ -179,11 +179,11 @@ static struct my_option my_long_options[] = {"data-file-length", 'D', "Max length of data file (when recreating data-file when it's full).", (gptr*) &check_param.max_data_file_length, - (gptr*) &check_param.max_data_file_length, 0, GET_LONG, REQUIRED_ARG, + (gptr*) &check_param.max_data_file_length, 0, GET_LL, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"extend-check", 'e', "Try to recover every possible row from the data file. Normally this will also find a lot of garbage rows; Don't use this option if you are not totally desperate.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"fast", 'F', "Check only tables that hasn't been closed properly.", 0, 0, 0, + {"fast", 'F', "Check only tables that haven't been closed properly.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, {"force", 'f', "Restart with -r if there are any errors in the table. States will be updated as with --update-state.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, @@ -196,7 +196,7 @@ static struct my_option my_long_options[] = {"keys-used", 'k', "Tell MyISAM to update only some specific keys. # is a bit mask of which keys to use. This can be used to get faster inserts!", (gptr*) &check_param.keys_in_use, (gptr*) &check_param.keys_in_use, 0, - GET_LL, REQUIRED_ARG, -1, 0, 0, 0, 0, 0}, + GET_ULL, REQUIRED_ARG, -1, 0, 0, 0, 0, 0}, {"medium-check", 'm', "Faster than extended-check, but only finds 99.99% of all errors. Should be good enough for most cases.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, @@ -211,16 +211,16 @@ static struct my_option my_long_options[] = "Uses old recovery method; Slower than '-r' but can handle a couple of cases where '-r' reports that it can't fix the data file.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, {"start-check-pos", OPT_START_CHECK_POS, "No help available.", 0, 0, 0, - GET_LONG, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + GET_ULL, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"set-auto-increment", 'A', "Force auto_increment to start at this or higher value. If no value is given, then sets the next auto_increment value to the highest used value for the auto key + 1.", (gptr*) &check_param.auto_increment_value, - (gptr*) &check_param.auto_increment_value, 0, GET_LONG, OPT_ARG, 0, 0, 0, + (gptr*) &check_param.auto_increment_value, 0, GET_ULL, OPT_ARG, 0, 0, 0, 0, 0, 0}, {"set-character-set", OPT_SET_CHARSET, "Change the character set used by the index", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"set-variable", 'O', - "Change the value of a variable. Please note that this option is depricated; you can set variables directly with --variable-name=value.", + "Change the value of a variable. Please note that this option is deprecated; you can set variables directly with --variable-name=value.", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"silent", 's', "Only print errors. One can use two -s to make myisamchk very silent.", 0, @@ -231,7 +231,7 @@ static struct my_option my_long_options[] = {"sort-records", 'R', "Sort records according to an index. This makes your data much more localized and may speed up things. (It may be VERY slow to do a sort the first time!)", (gptr*) &check_param.opt_sort_key, (gptr*) &check_param.opt_sort_key, 0, - GET_LONG, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"sort-recover", 'n', "Force recovering with sorting even if the temporary file was very big.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, @@ -250,7 +250,7 @@ static struct my_option my_long_options[] = 0, 0, 0, 0}, { "key_buffer_size", OPT_KEY_BUFFER_SIZE, "", (gptr*) &check_param.use_buffers, (gptr*) &check_param.use_buffers, 0, - GET_LONG, REQUIRED_ARG, (long) USE_BUFFER_INIT, (long) MALLOC_OVERHEAD, + GET_ULONG, REQUIRED_ARG, (long) USE_BUFFER_INIT, (long) MALLOC_OVERHEAD, (long) ~0L, (long) MALLOC_OVERHEAD, (long) IO_SIZE, 0}, { "myisam_block_size", OPT_MYISAM_BLOCK_SIZE, "", (gptr*) &opt_myisam_block_size, (gptr*) &opt_myisam_block_size, 0, @@ -258,41 +258,41 @@ static struct my_option my_long_options[] = MI_MAX_KEY_BLOCK_LENGTH, 0, MI_MIN_KEY_BLOCK_LENGTH, 0}, { "read_buffer_size", OPT_READ_BUFFER_SIZE, "", (gptr*) &check_param.read_buffer_length, - (gptr*) &check_param.read_buffer_length, 0, GET_LONG, REQUIRED_ARG, + (gptr*) &check_param.read_buffer_length, 0, GET_ULONG, REQUIRED_ARG, (long) READ_BUFFER_INIT, (long) MALLOC_OVERHEAD, (long) ~0L, (long) MALLOC_OVERHEAD, (long) 1L, 0}, { "write_buffer_size", OPT_WRITE_BUFFER_SIZE, "", (gptr*) &check_param.write_buffer_length, - (gptr*) &check_param.write_buffer_length, 0, GET_LONG, REQUIRED_ARG, + (gptr*) &check_param.write_buffer_length, 0, GET_ULONG, REQUIRED_ARG, (long) READ_BUFFER_INIT, (long) MALLOC_OVERHEAD, (long) ~0L, (long) MALLOC_OVERHEAD, (long) 1L, 0}, { "sort_buffer_size", OPT_SORT_BUFFER_SIZE, "", (gptr*) &check_param.sort_buffer_length, - (gptr*) &check_param.sort_buffer_length, 0, GET_LONG, REQUIRED_ARG, + (gptr*) &check_param.sort_buffer_length, 0, GET_ULONG, REQUIRED_ARG, (long) SORT_BUFFER_INIT, (long) (MIN_SORT_BUFFER + MALLOC_OVERHEAD), (long) ~0L, (long) MALLOC_OVERHEAD, (long) 1L, 0}, { "sort_key_blocks", OPT_SORT_KEY_BLOCKS, "", (gptr*) &check_param.sort_key_blocks, - (gptr*) &check_param.sort_key_blocks, 0, GET_LONG, REQUIRED_ARG, + (gptr*) &check_param.sort_key_blocks, 0, GET_ULONG, REQUIRED_ARG, BUFFERS_WHEN_SORTING, 4L, 100L, 0L, 1L, 0}, { "decode_bits", OPT_DECODE_BITS, "", (gptr*) &decode_bits, - (gptr*) &decode_bits, 0, GET_LONG, REQUIRED_ARG, 9L, 4L, 17L, 0L, 1L, 0}, + (gptr*) &decode_bits, 0, GET_UINT, REQUIRED_ARG, 9L, 4L, 17L, 0L, 1L, 0}, { "ft_min_word_len", OPT_FT_MIN_WORD_LEN, "", (gptr*) &ft_min_word_len, - (gptr*) &ft_min_word_len, 0, GET_LONG, REQUIRED_ARG, 4, 1, HA_FT_MAXLEN, + (gptr*) &ft_min_word_len, 0, GET_ULONG, REQUIRED_ARG, 4, 1, HA_FT_MAXLEN, 0, 1, 0}, { "ft_max_word_len", OPT_FT_MAX_WORD_LEN, "", (gptr*) &ft_max_word_len, - (gptr*) &ft_max_word_len, 0, GET_LONG, REQUIRED_ARG, HA_FT_MAXLEN, 10, + (gptr*) &ft_max_word_len, 0, GET_ULONG, REQUIRED_ARG, HA_FT_MAXLEN, 10, HA_FT_MAXLEN, 0, 1, 0}, { "ft_max_word_len_for_sort", OPT_FT_MAX_WORD_LEN_FOR_SORT, "", (gptr*) &ft_max_word_len_for_sort, (gptr*) &ft_max_word_len_for_sort, 0, - GET_LONG, REQUIRED_ARG, 20, 4, HA_FT_MAXLEN, 0, 1, 0}, + GET_ULONG, REQUIRED_ARG, 20, 4, HA_FT_MAXLEN, 0, 1, 0}, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }; static void print_version(void) { - printf("%s Ver 2.3 for %s at %s\n", my_progname, SYSTEM_TYPE, + printf("%s Ver 2.6 for %s at %s\n", my_progname, SYSTEM_TYPE, MACHINE_TYPE); } @@ -322,9 +322,9 @@ static void usage(void) -e, --extend-check Check the table VERY throughly. Only use this in\n\ extreme cases as myisamchk should normally be able to\n\ find out if the table is ok even without this switch\n\ - -F, --fast Check only tables that hasn't been closed properly\n\ + -F, --fast Check only tables that haven't been closed properly\n\ -C, --check-only-changed\n\ - Check only tables that has changed since last check\n\ + Check only tables that have changed since last check\n\ -f, --force Restart with -r if there are any errors in the table.\n\ States will be updated as with --update-state\n\ -i, --information Print statistics information about table that is checked\n\ @@ -380,7 +380,6 @@ static void usage(void) (It may be VERY slow to do a sort the first time!)"); print_defaults("my", load_default_groups); - putchar('\n'); my_print_variables(my_long_options); } @@ -616,13 +615,15 @@ get_one_option(int optid, static void get_options(register int *argc,register char ***argv) { + int ho_error; + load_defaults("my", load_default_groups, argc, argv); default_argv= *argv; if (isatty(fileno(stdout))) check_param.testflag|=T_WRITE_LOOP; - if (handle_options(argc, argv, my_long_options, get_one_option)) - exit(1); + if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option))) + exit(ho_error); /* If using repair, then update checksum if one uses --update-state */ if ((check_param.testflag & T_UPDATE_STATE) && @@ -733,7 +734,7 @@ static int myisamchk(MI_CHECK *param, my_string filename) raid_chunks=share->base.raid_chunks; /* - Skipp the checking of the file if: + Skip the checking of the file if: We are using --fast and the table is closed properly We are using --check-only-changed-tables and the table hasn't changed */ diff --git a/myisam/myisampack.c b/myisam/myisampack.c index bdd217a3643..e463978bc10 100644 --- a/myisam/myisampack.c +++ b/myisam/myisampack.c @@ -30,7 +30,7 @@ #ifndef __GNU_LIBRARY__ #define __GNU_LIBRARY__ /* Skip warnings in getopt.h */ #endif -#include <getopt.h> +#include <my_getopt.h> #if INT_MAX > 32767 #define BITS_SAVED 32 @@ -169,9 +169,10 @@ static int mrg_rrnd(PACK_MRG_INFO *info,byte *buf); static void mrg_reset(PACK_MRG_INFO *mrg); -static int backup=0,error_on_write=0,test_only=0,verbose=0,silent=0, - write_loop=0,force_pack=0,opt_wait=0,isamchk_neaded=0; +static int error_on_write=0,test_only=0,verbose=0,silent=0, + write_loop=0,force_pack=0, isamchk_neaded=0; static int tmpfile_createflag=O_RDWR | O_TRUNC | O_EXCL; +static my_bool backup, opt_wait; static uint tree_buff_length=8196-MALLOC_OVERHEAD; static char tmp_dir[FN_REFLEN]={0},*join_table; static my_off_t intervall_length; @@ -232,27 +233,43 @@ int main(int argc, char **argv) enum options_mp {OPT_CHARSETS_DIR_MP=256}; -static struct option long_options[] = +static struct my_option my_long_options[] = { - {"backup", no_argument, 0, 'b'}, - {"character-sets-dir",required_argument,0, OPT_CHARSETS_DIR_MP}, - {"debug", optional_argument, 0, '#'}, - {"force", no_argument, 0, 'f'}, - {"join", required_argument, 0, 'j'}, - {"help", no_argument, 0, '?'}, - {"packlength",required_argument, 0, 'p'}, - {"silent", no_argument, 0, 's'}, - {"tmpdir", required_argument, 0, 'T'}, - {"test", no_argument, 0, 't'}, - {"verbose", no_argument, 0, 'v'}, - {"version", no_argument, 0, 'V'}, - {"wait", no_argument, 0, 'w'}, - {0, 0, 0, 0} + {"backup", 'b', "Make a backup of the table as table_name.OLD", + (gptr*) &backup, (gptr*) &backup, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"character-sets-dir", OPT_CHARSETS_DIR_MP, + "Directory where character sets are.", (gptr*) &charsets_dir, + (gptr*) &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"debug", '#', "Output debug log. Often this is 'd:t:o,filename'", + 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, + {"force", 'f', + "Force packing of table even if it gets bigger or if tempfile exists.", + 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"join", 'j', + "Join all given tables into 'new_table_name'. All tables MUST have identical layouts.", + (gptr*) &join_table, (gptr*) &join_table, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, + 0, 0, 0}, + {"help", '?', "Display this help and exit.", + 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"silent", 's', "Be more silent.", + 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"tmpdir", 'T', "Use temporary directory to store temporary table.", + 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"test", 't', "Don't pack table, only test packing it.", + 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"verbose", 'v', "Write info about progress and packing result.", + 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"version", 'V', "Output version information and exit.", + 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"wait", 'w', "Wait and retry if table is in use.", (gptr*) &opt_wait, + (gptr*) &opt_wait, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} }; + static void print_version(void) { - printf("%s Ver 1.12 for %s on %s\n",my_progname,SYSTEM_TYPE,MACHINE_TYPE); + printf("%s Ver 1.21 for %s on %s\n", my_progname, SYSTEM_TYPE, MACHINE_TYPE); } static void usage(void) @@ -268,22 +285,54 @@ static void usage(void) puts("You should give the .MSI file as the filename argument."); printf("\nUsage: %s [OPTIONS] filename...\n", my_progname); - puts("\n\ - -b, --backup Make a backup of the table as table_name.OLD\n\ - -f, --force Force packing of table even if it gets bigger or if\n\ - tempfile exists.\n\ - -j, --join='new_table_name'\n\ - Join all given tables into 'new_table_name'.\n\ - All tables MUST have identical layouts.\n\ - -s, --silent Be more silent.\n\ - -t, --test Don't pack table, only test packing it.\n\ - -v, --verbose Write info about progress and packing result.\n\ - -w, --wait Wait and retry if table is in use.\n\ - -T, --tmpdir=... Use temporary directory to store temporary table.\n\ - -#, --debug=... Output debug log. Often this is 'd:t:o,filename`\n\ - -?, --help Display this help and exit.\n\ - -V, --version Output version information and exit."); - print_defaults("my",load_default_groups); + my_print_help(my_long_options); + print_defaults("my", load_default_groups); + my_print_variables(my_long_options); +} + + +static my_bool +get_one_option(int optid, const struct my_option *opt __attribute__((unused)), + char *argument) +{ + uint length; + + switch(optid) { + case 'f': + force_pack= 1; + tmpfile_createflag= O_RDWR | O_TRUNC; + break; + case 's': + write_loop= verbose= 0; + silent= 1; + break; + case 't': + test_only= verbose= 1; + break; + case 'T': + length= (uint) (strmov(tmp_dir, argument) - tmp_dir); + if (length != dirname_length(tmp_dir)) + { + tmp_dir[length]=FN_LIBCHAR; + tmp_dir[length+1]=0; + } + break; + case 'v': + verbose= 1; + silent= 0; + break; + case '#': + DBUG_PUSH(argument ? argument : "d:t:o"); + break; + case 'V': + print_version(); + exit(0); + case 'I': + case '?': + usage(); + exit(0); + } + return 0; } /* reads options */ @@ -291,66 +340,15 @@ static void usage(void) static void get_options(int *argc,char ***argv) { - int c,option_index=0; - uint length; + int ho_error; my_progname= argv[0][0]; if (isatty(fileno(stdout))) write_loop=1; - while ((c=getopt_long(*argc,*argv,"bfj:stvwT:#::?V",long_options, - &option_index)) != EOF) - { - switch(c) { - case 'b': - backup=1; - break; - case 'f': - force_pack=1; - tmpfile_createflag=O_RDWR | O_TRUNC; - break; - case 'j': - join_table=optarg; - break; - case 's': - write_loop=verbose=0; silent=1; - break; - case 't': - test_only=verbose=1; - break; - case 'T': - length=(uint) (strmov(tmp_dir,optarg)-tmp_dir); - if (length != dirname_length(tmp_dir)) - { - tmp_dir[length]=FN_LIBCHAR; - tmp_dir[length+1]=0; - } - break; - case 'v': - verbose=1; silent=0; - break; - case 'w': - opt_wait=1; - break; - case '#': - DBUG_PUSH(optarg ? optarg : "d:t:o"); - break; - case OPT_CHARSETS_DIR_MP: - charsets_dir = optarg; - break; - case 'V': print_version(); exit(0); - case 'I': - case '?': - usage(); - exit(0); - default: - fprintf(stderr,"%s: Illegal option: -%c\n",my_progname,opterr); - usage(); - exit(1); - } - } - (*argc)-=optind; - (*argv)+=optind; + if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option))) + exit(ho_error); + if (!*argc) { usage(); diff --git a/myisam/sort.c b/myisam/sort.c index 66a8254732a..bec77b231b8 100644 --- a/myisam/sort.c +++ b/myisam/sort.c @@ -122,7 +122,7 @@ int _create_index_by_sort(MI_SORT_PARAM *info,my_bool no_messages, if ((sort_keys=(uchar **)my_malloc(keys*(sort_length+sizeof(char*))+ HA_FT_MAXLEN, MYF(0)))) { - if (init_dynamic_array(&buffpek, sizeof(BUFFPEK), maxbuffer, + if (my_init_dynamic_array(&buffpek, sizeof(BUFFPEK), maxbuffer, maxbuffer/2)) my_free((gptr) sort_keys,MYF(0)); else |