Commit 73d43101 authored by unknown's avatar unknown

Merge serg@work.mysql.com:/home/bk/mysql

into infomag.ape.relarn.ru:/usr/home/serg/src/mysql.safe/bk/mysql


Docs/manual.texi:
  Auto merged
parents 44e3d4cd ca04c0ec
This diff is collapsed.
...@@ -45,6 +45,7 @@ my_config.h: ../config.h ...@@ -45,6 +45,7 @@ my_config.h: ../config.h
# This should be changed in the source and removed. # This should be changed in the source and removed.
my_global.h: global.h my_global.h: global.h
-$(RM) my_global.h
$(CP) global.h my_global.h $(CP) global.h my_global.h
# These files should not be included in distributions since they are # These files should not be included in distributions since they are
......
...@@ -40,6 +40,8 @@ typedef struct st_ft_doclist { ...@@ -40,6 +40,8 @@ typedef struct st_ft_doclist {
FT_DOC doc[1]; FT_DOC doc[1];
} FT_DOCLIST; } FT_DOCLIST;
extern const char *ft_precompiled_stopwords[];
int ft_init_stopwords(const char **); int ft_init_stopwords(const char **);
FT_DOCLIST * ft_init_search(void *, uint, byte *, uint, my_bool); FT_DOCLIST * ft_init_search(void *, uint, byte *, uint, my_bool);
......
...@@ -158,6 +158,7 @@ FT_DOCLIST * ft_init_search(void *info, uint keynr, byte *key, ...@@ -158,6 +158,7 @@ FT_DOCLIST * ft_init_search(void *info, uint keynr, byte *key,
ALL_IN_ONE aio; ALL_IN_ONE aio;
FT_DOCLIST *dlist; FT_DOCLIST *dlist;
FT_DOC *dptr; FT_DOC *dptr;
my_off_t saved_lastpos;
/* black magic ON */ /* black magic ON */
if ((int) (keynr = _mi_check_index((MI_INFO *)info,keynr)) < 0) if ((int) (keynr = _mi_check_index((MI_INFO *)info,keynr)) < 0)
...@@ -173,6 +174,8 @@ FT_DOCLIST * ft_init_search(void *info, uint keynr, byte *key, ...@@ -173,6 +174,8 @@ FT_DOCLIST * ft_init_search(void *info, uint keynr, byte *key,
aio.keyinfo=aio.info->s->keyinfo+keynr; aio.keyinfo=aio.info->s->keyinfo+keynr;
aio.key_root=aio.info->s->state.key_root[keynr]; aio.key_root=aio.info->s->state.key_root[keynr];
saved_lastpos=aio.info->lastpos;
if(!(wtree=ft_parse(NULL,key,key_len))) return NULL; if(!(wtree=ft_parse(NULL,key,key_len))) return NULL;
init_tree(&aio.dtree,0,sizeof(FT_SUPERDOC),(qsort_cmp)&FT_SUPERDOC_cmp,0, init_tree(&aio.dtree,0,sizeof(FT_SUPERDOC),(qsort_cmp)&FT_SUPERDOC_cmp,0,
...@@ -199,6 +202,7 @@ FT_DOCLIST * ft_init_search(void *info, uint keynr, byte *key, ...@@ -199,6 +202,7 @@ FT_DOCLIST * ft_init_search(void *info, uint keynr, byte *key,
} }
err: err:
aio.info->lastpos=saved_lastpos;
delete_tree(&aio.dtree); delete_tree(&aio.dtree);
delete_tree(wtree); delete_tree(wtree);
free(wtree); free(wtree);
...@@ -217,7 +221,8 @@ int ft_read_next(FT_DOCLIST *handler, char *record) ...@@ -217,7 +221,8 @@ int ft_read_next(FT_DOCLIST *handler, char *record)
info->update&= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED); info->update&= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED);
if (!(*info->read_record)(info,handler->doc[handler->curdoc].dpos,record)) info->lastpos=handler->doc[handler->curdoc].dpos;
if (!(*info->read_record)(info,info->lastpos,record))
{ {
info->update|= HA_STATE_AKTIV; /* Record is read */ info->update|= HA_STATE_AKTIV; /* Record is read */
return 0; return 0;
......
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB /* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or the Free Software Foundation; either version 2 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
...@@ -35,8 +35,6 @@ ...@@ -35,8 +35,6 @@
extern const MI_KEYSEG ft_keysegs[FT_SEGS]; extern const MI_KEYSEG ft_keysegs[FT_SEGS];
extern const char *ft_precompiled_stopwords[];
int _mi_ft_cmp(MI_INFO *, uint, const byte *, const byte *); int _mi_ft_cmp(MI_INFO *, uint, const byte *, const byte *);
int _mi_ft_add(MI_INFO *, uint, byte *, const byte *, my_off_t); int _mi_ft_add(MI_INFO *, uint, byte *, const byte *, my_off_t);
int _mi_ft_del(MI_INFO *, uint, byte *, const byte *, my_off_t); int _mi_ft_del(MI_INFO *, uint, byte *, const byte *, my_off_t);
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB /* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or the Free Software Foundation; either version 2 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
...@@ -1083,7 +1083,7 @@ int mi_repair(MI_CHECK *param, register MI_INFO *info, ...@@ -1083,7 +1083,7 @@ int mi_repair(MI_CHECK *param, register MI_INFO *info,
if (!(sort_info->record=(byte*) my_malloc((uint) share->base.pack_reclength, if (!(sort_info->record=(byte*) my_malloc((uint) share->base.pack_reclength,
MYF(0)))) MYF(0))))
{ {
mi_check_print_error(param,"Not Enough memory for extra record"); mi_check_print_error(param,"Not enough memory for extra record");
goto err; goto err;
} }
...@@ -1141,6 +1141,14 @@ int mi_repair(MI_CHECK *param, register MI_INFO *info, ...@@ -1141,6 +1141,14 @@ int mi_repair(MI_CHECK *param, register MI_INFO *info,
for (i=0 ; i < share->state.header.max_block_size ; i++) for (i=0 ; i < share->state.header.max_block_size ; i++)
share->state.key_del[i]= HA_OFFSET_ERROR; share->state.key_del[i]= HA_OFFSET_ERROR;
/* I think mi_repair and mi_repair_by_sort should do the same
(according, e.g. to ha_myisam::repair), but as mi_repair doesn't
touch key_map it cannot be used to T_CREATE_MISSING_KEYS.
That is the next line for... (serg)
*/
share->state.key_map= ((ulonglong)1L << share->base.keys)-1;
info->state->key_file_length=share->base.keystart; info->state->key_file_length=share->base.keystart;
lock_memory(param); /* Everything is alloced */ lock_memory(param); /* Everything is alloced */
...@@ -1271,8 +1279,15 @@ static int writekeys(register MI_INFO *info,byte *buff,my_off_t filepos) ...@@ -1271,8 +1279,15 @@ static int writekeys(register MI_INFO *info,byte *buff,my_off_t filepos)
{ {
if (((ulonglong) 1 << i) & info->s->state.key_map) if (((ulonglong) 1 << i) & info->s->state.key_map)
{ {
uint key_length=_mi_make_key(info,i,key,buff,filepos); if (info->s->keyinfo[i].flag & HA_FULLTEXT )
if (_mi_ck_write(info,i,key,key_length)) goto err; {
if (_mi_ft_add(info,i,(char*) key,buff,filepos)) goto err;
}
else
{
uint key_length=_mi_make_key(info,i,key,buff,filepos);
if (_mi_ck_write(info,i,key,key_length)) goto err;
}
} }
} }
DBUG_RETURN(0); DBUG_RETURN(0);
...@@ -1285,8 +1300,15 @@ static int writekeys(register MI_INFO *info,byte *buff,my_off_t filepos) ...@@ -1285,8 +1300,15 @@ static int writekeys(register MI_INFO *info,byte *buff,my_off_t filepos)
{ {
if (((ulonglong) 1 << i) & info->s->state.key_map) if (((ulonglong) 1 << i) & info->s->state.key_map)
{ {
uint key_length=_mi_make_key(info,i,key,buff,filepos); if (info->s->keyinfo[i].flag & HA_FULLTEXT)
if (_mi_ck_delete(info,i,key,key_length)) break; {
if (_mi_ft_del(info,i,(char*) key,buff,filepos)) break;
}
else
{
uint key_length=_mi_make_key(info,i,key,buff,filepos);
if (_mi_ck_delete(info,i,key,key_length)) break;
}
} }
} }
} }
...@@ -1919,8 +1941,22 @@ static int sort_key_read(SORT_INFO *sort_info, void *key) ...@@ -1919,8 +1941,22 @@ static int sort_key_read(SORT_INFO *sort_info, void *key)
"Found too many records; Can`t continue"); "Found too many records; Can`t continue");
DBUG_RETURN(1); DBUG_RETURN(1);
} }
VOID(_mi_make_key(info,sort_info->key,key,sort_info->record, /* Hmm, repair_by_sort uses find_all_keys, and find_all_keys strictly
sort_info->filepos)); implies "one row - one key per keynr", while for ft_key one row/keynr
can produce as many keys as the number of unique words in the text
that's why I disabled repair_by_sort for ft-keys. (serg)
*/
if (sort_info->keyinfo->flag & HA_FULLTEXT )
{
mi_check_print_error(sort_info->param,
"Can`t use repair_by_sort with FULLTEXT key");
DBUG_RETURN(1);
}
else
{
VOID(_mi_make_key(info,sort_info->key,key,sort_info->record,
sort_info->filepos));
}
DBUG_RETURN(sort_write_record(sort_info)); DBUG_RETURN(sort_write_record(sort_info));
} /* sort_key_read */ } /* sort_key_read */
...@@ -2984,7 +3020,14 @@ my_bool mi_test_if_sort_rep(MI_INFO *info, ha_rows rows) ...@@ -2984,7 +3020,14 @@ my_bool mi_test_if_sort_rep(MI_INFO *info, ha_rows rows)
return FALSE; /* Can't use sort */ return FALSE; /* Can't use sort */
for (i=0 ; i < share->base.keys ; i++,key++) for (i=0 ; i < share->base.keys ; i++,key++)
{ {
if (mi_too_big_key_for_sort(key,rows)) /* It's to disable repair_by_sort for ft-keys.
Another solution would be to make ft-keys just too_big_key_for_sort,
but then they won't be disabled by dectivate_non_unique_index
and so they will be created at the first stage. As ft-key creation
is very time-consuming process, it's better to leave it to repair stage
but this repair shouldn't be repair_by_sort (serg)
*/
if (mi_too_big_key_for_sort(key,rows) || (key->flag & HA_FULLTEXT))
return FALSE; return FALSE;
} }
return TRUE; return TRUE;
......
...@@ -372,6 +372,7 @@ int ha_myisam::repair(THD *thd, MI_CHECK &param) ...@@ -372,6 +372,7 @@ int ha_myisam::repair(THD *thd, MI_CHECK &param)
param.table_name = table->table_name; param.table_name = table->table_name;
param.tmpfile_createflag = O_RDWR | O_TRUNC; param.tmpfile_createflag = O_RDWR | O_TRUNC;
param.using_global_keycache = 1; param.using_global_keycache = 1;
param.thd=thd;
VOID(fn_format(fixed_name,file->filename,"",MI_NAME_IEXT, VOID(fn_format(fixed_name,file->filename,"",MI_NAME_IEXT,
4+ (param.opt_follow_links ? 16 : 0))); 4+ (param.opt_follow_links ? 16 : 0)));
......
...@@ -1837,26 +1837,8 @@ longlong Item_func_inet_aton::val_int() ...@@ -1837,26 +1837,8 @@ longlong Item_func_inet_aton::val_int()
double Item_func_match::val() double Item_func_match::val()
{ {
my_off_t docid=table->file->row_position(); // HAVE to do it here...
if (first_call) if (first_call)
{ init_search();
if (join_key=(table->file->get_index() == key &&
(ft_handler=(FT_DOCLIST *)table->file->ft_handler)))
;
else
{
/* join won't use this ft-key, but we must to init it anyway */
String *ft_tmp=0;
char tmp1[FT_QUERY_MAXLEN];
String tmp2(tmp1,sizeof(tmp1));
ft_tmp=key_item()->val_str(&tmp2);
ft_handler=(FT_DOCLIST *)
table->file->ft_init_ext(key, (byte*) ft_tmp->ptr(), ft_tmp->length());
}
first_call=0;
}
// Don't know how to return an error from val(), so NULL will be returned // Don't know how to return an error from val(), so NULL will be returned
if ((null_value=(ft_handler==NULL))) if ((null_value=(ft_handler==NULL)))
...@@ -1873,6 +1855,7 @@ double Item_func_match::val() ...@@ -1873,6 +1855,7 @@ double Item_func_match::val()
int a,b,c; int a,b,c;
FT_DOC *docs=ft_handler->doc; FT_DOC *docs=ft_handler->doc;
my_off_t docid=table->file->row_position();
if ((null_value=(docid==HA_OFFSET_ERROR))) if ((null_value=(docid==HA_OFFSET_ERROR)))
return 0.0; return 0.0;
...@@ -1893,6 +1876,36 @@ double Item_func_match::val() ...@@ -1893,6 +1876,36 @@ double Item_func_match::val()
} }
} }
void Item_func_match::init_search()
{
if (!first_call)
return;
first_call=false;
if (master)
{
master->init_search();
ft_handler=master->ft_handler;
join_key=master->join_key;
return;
}
if (join_key)
{
ft_handler=((FT_DOCLIST *)table->file->ft_handler);
return;
}
/* join won't use this ft-key, but we must to init it anyway */
String *ft_tmp=0;
char tmp1[FT_QUERY_MAXLEN];
String tmp2(tmp1,sizeof(tmp1));
ft_tmp=key_item()->val_str(&tmp2);
ft_handler=(FT_DOCLIST *)
table->file->ft_init_ext(key, (byte*) ft_tmp->ptr(), ft_tmp->length());
}
bool Item_func_match::fix_fields(THD *thd,struct st_table_list *tlist) bool Item_func_match::fix_fields(THD *thd,struct st_table_list *tlist)
{ {
List_iterator<Item> li(fields); List_iterator<Item> li(fields);
...@@ -1982,6 +1995,24 @@ bool Item_func_match::fix_index() ...@@ -1982,6 +1995,24 @@ bool Item_func_match::fix_index()
this->key=max_key; this->key=max_key;
first_call=1; first_call=1;
maybe_null=1; maybe_null=1;
join_key=0;
return 0;
}
bool Item_func_match::eq(const Item *item) const
{
if (item->type() != FUNC_ITEM)
return 0;
if (func_name() != ((Item_func*)item)->func_name())
return 0;
Item_func_match *ifm=(Item_func_match*) item;
if (key == ifm->key && table == ifm->table &&
key_item()->eq(ifm->key_item()))
return 1;
return 0; return 0;
} }
......
...@@ -839,19 +839,28 @@ class Item_func_match :public Item_real_func ...@@ -839,19 +839,28 @@ class Item_func_match :public Item_real_func
TABLE *table; TABLE *table;
uint key; uint key;
bool first_call, join_key; bool first_call, join_key;
Item_func_match *master;
FT_DOCLIST *ft_handler; FT_DOCLIST *ft_handler;
Item_func_match(List<Item> &a, Item *b): Item_real_func(b), Item_func_match(List<Item> &a, Item *b): Item_real_func(b),
fields(a), table(0), ft_handler(0) fields(a), table(0), ft_handler(0), master(0) {}
{} ~Item_func_match()
~Item_func_match() { ft_close_search(ft_handler); {
if(join_key) table->file->ft_handler=0; } if (!master)
{
ft_close_search(ft_handler);
if(join_key)
table->file->ft_handler=0;
}
}
const char *func_name() const { return "match"; } const char *func_name() const { return "match"; }
enum Functype functype() const { return FT_FUNC; } enum Functype functype() const { return FT_FUNC; }
void update_used_tables() {} void update_used_tables() {}
bool fix_fields(THD *thd,struct st_table_list *tlist); bool fix_fields(THD *thd,struct st_table_list *tlist);
bool fix_index(); bool eq(const Item *) const;
double val(); double val();
longlong val_int() { return val()!=0.0; } longlong val_int() { return val()!=0.0; }
bool fix_index();
void init_search();
}; };
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB /* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or the Free Software Foundation; either version 2 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
...@@ -81,7 +81,6 @@ static SYMBOL symbols[] = { ...@@ -81,7 +81,6 @@ static SYMBOL symbols[] = {
{ "CHANGED", SYM(CHANGED),0,0}, { "CHANGED", SYM(CHANGED),0,0},
{ "CHECK", SYM(CHECK_SYM),0,0}, { "CHECK", SYM(CHECK_SYM),0,0},
{ "CHECKSUM", SYM(CHECKSUM_SYM),0,0}, { "CHECKSUM", SYM(CHECKSUM_SYM),0,0},
{ "COLLECTION", SYM(COLLECTION),0,0},
{ "COLUMN", SYM(COLUMN_SYM),0,0}, { "COLUMN", SYM(COLUMN_SYM),0,0},
{ "COLUMNS", SYM(COLUMNS),0,0}, { "COLUMNS", SYM(COLUMNS),0,0},
{ "COMMENT", SYM(COMMENT_SYM),0,0}, { "COMMENT", SYM(COMMENT_SYM),0,0},
...@@ -142,6 +141,7 @@ static SYMBOL symbols[] = { ...@@ -142,6 +141,7 @@ static SYMBOL symbols[] = {
{ "FROM", SYM(FROM),0,0}, { "FROM", SYM(FROM),0,0},
{ "FOR", SYM(FOR_SYM),0,0}, { "FOR", SYM(FOR_SYM),0,0},
{ "FULL", SYM(FULL),0,0}, { "FULL", SYM(FULL),0,0},
{ "FULLTEXT", SYM(FULLTEXT_SYM),0,0},
{ "FUNCTION", SYM(UDF_SYM),0,0}, { "FUNCTION", SYM(UDF_SYM),0,0},
{ "GRANT", SYM(GRANT),0,0}, { "GRANT", SYM(GRANT),0,0},
{ "GRANTS", SYM(GRANTS),0,0}, { "GRANTS", SYM(GRANTS),0,0},
...@@ -191,14 +191,14 @@ static SYMBOL symbols[] = { ...@@ -191,14 +191,14 @@ static SYMBOL symbols[] = {
{ "LONGBLOB", SYM(LONGBLOB),0,0}, { "LONGBLOB", SYM(LONGBLOB),0,0},
{ "LONGTEXT", SYM(LONGTEXT),0,0}, { "LONGTEXT", SYM(LONGTEXT),0,0},
{ "LOW_PRIORITY", SYM(LOW_PRIORITY),0,0}, { "LOW_PRIORITY", SYM(LOW_PRIORITY),0,0},
{ "MASTER", SYM(MASTER_SYM),0,0}, { "MASTER", SYM(MASTER_SYM),0,0},
{ "MASTER_CONNECT_RETRY", SYM(MASTER_CONNECT_RETRY_SYM),0,0}, { "MASTER_CONNECT_RETRY", SYM(MASTER_CONNECT_RETRY_SYM),0,0},
{ "MASTER_HOST", SYM(MASTER_HOST_SYM),0,0}, { "MASTER_HOST", SYM(MASTER_HOST_SYM),0,0},
{ "MASTER_LOG_FILE", SYM(MASTER_LOG_FILE_SYM),0,0}, { "MASTER_LOG_FILE", SYM(MASTER_LOG_FILE_SYM),0,0},
{ "MASTER_LOG_POS", SYM(MASTER_LOG_POS_SYM),0,0}, { "MASTER_LOG_POS", SYM(MASTER_LOG_POS_SYM),0,0},
{ "MASTER_PASSWORD", SYM(MASTER_PASSWORD_SYM),0,0}, { "MASTER_PASSWORD", SYM(MASTER_PASSWORD_SYM),0,0},
{ "MASTER_PORT", SYM(MASTER_PORT_SYM),0,0}, { "MASTER_PORT", SYM(MASTER_PORT_SYM),0,0},
{ "MASTER_USER", SYM(MASTER_USER_SYM),0,0}, { "MASTER_USER", SYM(MASTER_USER_SYM),0,0},
{ "MAX_ROWS", SYM(MAX_ROWS),0,0}, { "MAX_ROWS", SYM(MAX_ROWS),0,0},
{ "MATCH", SYM(MATCH),0,0}, { "MATCH", SYM(MATCH),0,0},
{ "MEDIUMBLOB", SYM(MEDIUMBLOB),0,0}, { "MEDIUMBLOB", SYM(MEDIUMBLOB),0,0},
......
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB /* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or the Free Software Foundation; either version 2 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
...@@ -875,7 +875,7 @@ void end_thread(THD *thd, bool put_in_cache) ...@@ -875,7 +875,7 @@ void end_thread(THD *thd, bool put_in_cache)
(void) pthread_mutex_lock(&LOCK_thread_count); (void) pthread_mutex_lock(&LOCK_thread_count);
thread_count--; thread_count--;
delete thd; delete thd;
if (put_in_cache && cached_thread_count < thread_cache_size && if (put_in_cache && cached_thread_count < thread_cache_size &&
! abort_loop && !kill_cached_threads) ! abort_loop && !kill_cached_threads)
{ {
...@@ -1455,7 +1455,7 @@ int main(int argc, char **argv) ...@@ -1455,7 +1455,7 @@ int main(int argc, char **argv)
sql_print_error("Can't init databases"); sql_print_error("Can't init databases");
exit(1); exit(1);
} }
ft_init_stopwords(NULL); /* SerG */ ft_init_stopwords(ft_precompiled_stopwords); /* SerG */
#ifdef __WIN__ #ifdef __WIN__
#define MYSQL_ERR_FILE "mysql.err" #define MYSQL_ERR_FILE "mysql.err"
...@@ -1531,12 +1531,12 @@ int main(int argc, char **argv) ...@@ -1531,12 +1531,12 @@ int main(int argc, char **argv)
// slave thread // slave thread
if(master_host) if(master_host)
{ {
pthread_t hThread; pthread_t hThread;
if(pthread_create(&hThread, &connection_attrib, handle_slave, 0)) if(pthread_create(&hThread, &connection_attrib, handle_slave, 0))
sql_print_error("Warning: Can't create thread to handle slave"); sql_print_error("Warning: Can't create thread to handle slave");
} }
printf(ER(ER_READY),my_progname,server_version,""); printf(ER(ER_READY),my_progname,server_version,"");
fflush(stdout); fflush(stdout);
...@@ -2179,7 +2179,7 @@ static struct option long_options[] = ...@@ -2179,7 +2179,7 @@ static struct option long_options[] =
{"log-update", optional_argument, 0, (int) OPT_UPDATE_LOG}, {"log-update", optional_argument, 0, (int) OPT_UPDATE_LOG},
{"log-slow-queries", optional_argument, 0, (int) OPT_SLOW_QUERY_LOG}, {"log-slow-queries", optional_argument, 0, (int) OPT_SLOW_QUERY_LOG},
{"log-long-format", no_argument, 0, (int) OPT_LONG_FORMAT}, {"log-long-format", no_argument, 0, (int) OPT_LONG_FORMAT},
{"log-slave-updates", no_argument,0, (int) OPT_LOG_SLAVE_UPDATES}, {"log-slave-updates", no_argument,0, (int) OPT_LOG_SLAVE_UPDATES},
{"low-priority-updates", no_argument, 0, (int) OPT_LOW_PRIORITY_UPDATES}, {"low-priority-updates", no_argument, 0, (int) OPT_LOW_PRIORITY_UPDATES},
{"master-host", required_argument, 0, (int) OPT_MASTER_HOST}, {"master-host", required_argument, 0, (int) OPT_MASTER_HOST},
{"master-user", required_argument, 0, (int) OPT_MASTER_USER}, {"master-user", required_argument, 0, (int) OPT_MASTER_USER},
...@@ -2209,7 +2209,7 @@ static struct option long_options[] = ...@@ -2209,7 +2209,7 @@ static struct option long_options[] =
{"skip-show-database",no_argument,0, (int) OPT_SKIP_SHOW_DB}, {"skip-show-database",no_argument,0, (int) OPT_SKIP_SHOW_DB},
{"skip-networking", no_argument,0, (int) OPT_SKIP_NETWORKING}, {"skip-networking", no_argument,0, (int) OPT_SKIP_NETWORKING},
{"skip-thread-priority", no_argument,0,(int) OPT_SKIP_PRIOR}, {"skip-thread-priority", no_argument,0,(int) OPT_SKIP_PRIOR},
{"sql-bin-update-same", no_argument, 0, (int)OPT_SQL_BIN_UPDATE_SAME}, {"sql-bin-update-same", no_argument, 0, (int)OPT_SQL_BIN_UPDATE_SAME},
#include "sslopt-longopts.h" #include "sslopt-longopts.h"
#ifdef __WIN__ #ifdef __WIN__
{"standalone", no_argument,0, (int) OPT_STANDALONE}, {"standalone", no_argument,0, (int) OPT_STANDALONE},
...@@ -2393,7 +2393,7 @@ struct show_var_st status_vars[]= { ...@@ -2393,7 +2393,7 @@ struct show_var_st status_vars[]= {
{"Questions", (char*) 0, SHOW_QUESTION}, {"Questions", (char*) 0, SHOW_QUESTION},
{"Slow_launch_threads", (char*) &slow_launch_threads, SHOW_LONG}, {"Slow_launch_threads", (char*) &slow_launch_threads, SHOW_LONG},
{"Slow_queries", (char*) &long_query_count, SHOW_LONG}, {"Slow_queries", (char*) &long_query_count, SHOW_LONG},
{"Slave_running", (char*) &slave_running, SHOW_BOOL}, {"Slave_running", (char*) &slave_running, SHOW_BOOL},
{"Threads_cached", (char*) &cached_thread_count, SHOW_LONG_CONST}, {"Threads_cached", (char*) &cached_thread_count, SHOW_LONG_CONST},
{"Threads_connected", (char*) &thread_count, SHOW_INT_CONST}, {"Threads_connected", (char*) &thread_count, SHOW_INT_CONST},
{"Threads_running", (char*) &thread_running, SHOW_INT_CONST}, {"Threads_running", (char*) &thread_running, SHOW_INT_CONST},
...@@ -2502,7 +2502,7 @@ static void usage(void) ...@@ -2502,7 +2502,7 @@ static void usage(void)
--bdb-tmpdir=directory Berkeley DB tempfile name\n\ --bdb-tmpdir=directory Berkeley DB tempfile name\n\
--skip-bdb Don't use berkeley db (will save memory)\n\ --skip-bdb Don't use berkeley db (will save memory)\n\
"); ");
#endif #endif
print_defaults("my",load_default_groups); print_defaults("my",load_default_groups);
puts(""); puts("");
...@@ -2687,39 +2687,39 @@ static void get_options(int argc,char **argv) ...@@ -2687,39 +2687,39 @@ static void get_options(int argc,char **argv)
break; break;
case (int) OPT_BIN_LOG: case (int) OPT_BIN_LOG:
opt_bin_log=1; opt_bin_log=1;
opt_bin_logname=optarg; opt_bin_logname=optarg;
break; break;
case (int) OPT_LOG_SLAVE_UPDATES: case (int) OPT_LOG_SLAVE_UPDATES:
opt_log_slave_updates = 1; opt_log_slave_updates = 1;
break; break;
case (int)OPT_REPLICATE_IGNORE_DB: case (int)OPT_REPLICATE_IGNORE_DB:
{ {
i_string *db = new i_string(optarg); i_string *db = new i_string(optarg);
replicate_ignore_db.push_back(db); replicate_ignore_db.push_back(db);
break; break;
} }
case (int)OPT_REPLICATE_DO_DB: case (int)OPT_REPLICATE_DO_DB:
{ {
i_string *db = new i_string(optarg); i_string *db = new i_string(optarg);
replicate_do_db.push_back(db); replicate_do_db.push_back(db);
break; break;
} }
case (int)OPT_BINLOG_IGNORE_DB: case (int)OPT_BINLOG_IGNORE_DB:
{ {
i_string *db = new i_string(optarg); i_string *db = new i_string(optarg);
binlog_ignore_db.push_back(db); binlog_ignore_db.push_back(db);
break; break;
} }
case (int)OPT_BINLOG_DO_DB: case (int)OPT_BINLOG_DO_DB:
{ {
i_string *db = new i_string(optarg); i_string *db = new i_string(optarg);
binlog_do_db.push_back(db); binlog_do_db.push_back(db);
break; break;
} }
case (int) OPT_SQL_BIN_UPDATE_SAME: case (int) OPT_SQL_BIN_UPDATE_SAME:
opt_sql_bin_update = 1; opt_sql_bin_update = 1;
break; break;
...@@ -2878,7 +2878,7 @@ static void get_options(int argc,char **argv) ...@@ -2878,7 +2878,7 @@ static void get_options(int argc,char **argv)
if (test_if_int(optarg,(uint) strlen(optarg))) if (test_if_int(optarg,(uint) strlen(optarg)))
berkeley_lock_scan_time=atoi(optarg); berkeley_lock_scan_time=atoi(optarg);
else else
{ {
fprintf(stderr,"Unknown lock type: %s\n",optarg); fprintf(stderr,"Unknown lock type: %s\n",optarg);
exit(1); exit(1);
} }
...@@ -3314,7 +3314,7 @@ static int get_service_parameters() ...@@ -3314,7 +3314,7 @@ static int get_service_parameters()
0 ) 0 )
{ {
SET_CHANGEABLE_VARVAL( "thread_concurrency" ); SET_CHANGEABLE_VARVAL( "thread_concurrency" );
} }
else else
{ {
TCHAR szErrorMsg [ 512 ]; TCHAR szErrorMsg [ 512 ];
...@@ -3341,7 +3341,7 @@ static int get_service_parameters() ...@@ -3341,7 +3341,7 @@ static int get_service_parameters()
static char *get_relative_path(const char *path) static char *get_relative_path(const char *path)
{ {
if (test_if_hard_path(path) && if (test_if_hard_path(path) &&
is_prefix(path,DEFAULT_MYSQL_HOME) && is_prefix(path,DEFAULT_MYSQL_HOME) &&
strcmp(DEFAULT_MYSQL_HOME,FN_ROOTDIR)) strcmp(DEFAULT_MYSQL_HOME,FN_ROOTDIR))
{ {
path+=(uint) strlen(DEFAULT_MYSQL_HOME); path+=(uint) strlen(DEFAULT_MYSQL_HOME);
......
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB /* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or the Free Software Foundation; either version 2 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
...@@ -58,7 +58,7 @@ static int send_file(THD *thd) ...@@ -58,7 +58,7 @@ static int send_file(THD *thd)
// the job // the job
old_timeout = thd->net.timeout; old_timeout = thd->net.timeout;
thd->net.timeout = thd->inactive_timeout; thd->net.timeout = thd->inactive_timeout;
// we need net_flush here because the client will not know it needs to send // we need net_flush here because the client will not know it needs to send
// us the file name until it has processed the load event entry // us the file name until it has processed the load event entry
if (net_flush(net) || (packet_len = my_net_read(net)) == packet_error) if (net_flush(net) || (packet_len = my_net_read(net)) == packet_error)
...@@ -67,16 +67,16 @@ static int send_file(THD *thd) ...@@ -67,16 +67,16 @@ static int send_file(THD *thd)
goto err; goto err;
} }
fn_format(fname, (char*)net->read_pos + 1, "", "", 4); fn_format(fname, (char*)net->read_pos + 1, "", "", 4);
if(!strcmp(fname,"/dev/null")) goto end; // this is needed to make replicate-ignore-db if(!strcmp(fname,"/dev/null")) goto end; // this is needed to make replicate-ignore-db
// work on the well-known system that does not have a /dev/null :-) // work on the well-known system that does not have a /dev/null :-)
if ((fd = my_open(fname, O_RDONLY, MYF(MY_WME))) < 0) if ((fd = my_open(fname, O_RDONLY, MYF(MY_WME))) < 0)
{ {
errmsg = "Failed on my_open()"; errmsg = "Failed on my_open()";
goto err; goto err;
} }
while ((bytes = (int) my_read(fd, (byte*) buf, sizeof(buf), while ((bytes = (int) my_read(fd, (byte*) buf, sizeof(buf),
MYF(MY_WME))) > 0) MYF(MY_WME))) > 0)
{ {
...@@ -87,7 +87,7 @@ static int send_file(THD *thd) ...@@ -87,7 +87,7 @@ static int send_file(THD *thd)
} }
} }
end: end:
if (my_net_write(net, "", 0) || net_flush(net) || if (my_net_write(net, "", 0) || net_flush(net) ||
(my_net_read(net) == packet_error)) (my_net_read(net) == packet_error))
{ {
...@@ -95,7 +95,7 @@ static int send_file(THD *thd) ...@@ -95,7 +95,7 @@ static int send_file(THD *thd)
goto err; goto err;
} }
error = 0; error = 0;
err: err:
thd->net.timeout = old_timeout; thd->net.timeout = old_timeout;
if(fd >= 0) if(fd >= 0)
...@@ -104,7 +104,7 @@ static int send_file(THD *thd) ...@@ -104,7 +104,7 @@ static int send_file(THD *thd)
{ {
sql_print_error("failed in send_file() : %s", errmsg); sql_print_error("failed in send_file() : %s", errmsg);
DBUG_PRINT("error", (errmsg)); DBUG_PRINT("error", (errmsg));
} }
DBUG_RETURN(error); DBUG_RETURN(error);
} }
...@@ -195,12 +195,12 @@ void mysql_binlog_send(THD* thd, char* log_ident, ulong pos, ushort flags) ...@@ -195,12 +195,12 @@ void mysql_binlog_send(THD* thd, char* log_ident, ulong pos, ushort flags)
errmsg = "Binary log is not open"; errmsg = "Binary log is not open";
goto err; goto err;
} }
if(log_ident[0]) if(log_ident[0])
mysql_bin_log.make_log_name(search_file_name, log_ident); mysql_bin_log.make_log_name(search_file_name, log_ident);
else else
search_file_name[0] = 0; search_file_name[0] = 0;
if(mysql_bin_log.find_first_log(&linfo, search_file_name)) if(mysql_bin_log.find_first_log(&linfo, search_file_name))
{ {
errmsg = "Could not find first log"; errmsg = "Could not find first log";
...@@ -219,8 +219,8 @@ void mysql_binlog_send(THD* thd, char* log_ident, ulong pos, ushort flags) ...@@ -219,8 +219,8 @@ void mysql_binlog_send(THD* thd, char* log_ident, ulong pos, ushort flags)
errmsg = "Error on fseek()"; errmsg = "Error on fseek()";
goto err; goto err;
} }
packet->length(0); packet->length(0);
packet->append("\0", 1); // we need to start a packet with something other than 255 packet->append("\0", 1); // we need to start a packet with something other than 255
// to distiquish it from error // to distiquish it from error
...@@ -251,7 +251,7 @@ void mysql_binlog_send(THD* thd, char* log_ident, ulong pos, ushort flags) ...@@ -251,7 +251,7 @@ void mysql_binlog_send(THD* thd, char* log_ident, ulong pos, ushort flags)
errmsg = "error reading log event"; errmsg = "error reading log event";
goto err; goto err;
} }
if(!(flags & BINLOG_DUMP_NON_BLOCK) && mysql_bin_log.is_active(log_file_name)) if(!(flags & BINLOG_DUMP_NON_BLOCK) && mysql_bin_log.is_active(log_file_name))
// block until there is more data in the log // block until there is more data in the log
// unless non-blocking mode requested // unless non-blocking mode requested
...@@ -267,10 +267,10 @@ void mysql_binlog_send(THD* thd, char* log_ident, ulong pos, ushort flags) ...@@ -267,10 +267,10 @@ void mysql_binlog_send(THD* thd, char* log_ident, ulong pos, ushort flags)
// if we did not miss anything, we just wait for other threads // if we did not miss anything, we just wait for other threads
// to signal us // to signal us
{ {
pthread_mutex_t *log_lock = mysql_bin_log.get_log_lock(); pthread_mutex_t *log_lock = mysql_bin_log.get_log_lock();
clearerr(log); clearerr(log);
// tell the kill thread how to wake us up // tell the kill thread how to wake us up
pthread_mutex_lock(&thd->mysys_var->mutex); pthread_mutex_lock(&thd->mysys_var->mutex);
thd->mysys_var->current_mutex = log_lock; thd->mysys_var->current_mutex = log_lock;
thd->mysys_var->current_cond = &COND_binlog_update; thd->mysys_var->current_cond = &COND_binlog_update;
...@@ -283,7 +283,7 @@ void mysql_binlog_send(THD* thd, char* log_ident, ulong pos, ushort flags) ...@@ -283,7 +283,7 @@ void mysql_binlog_send(THD* thd, char* log_ident, ulong pos, ushort flags)
pthread_mutex_lock(log_lock); // no one will update the log while we are reading pthread_mutex_lock(log_lock); // no one will update the log while we are reading
// now, but we'll be quick and just read one record // now, but we'll be quick and just read one record
switch(Log_event::read_log_event(log, packet)) switch(Log_event::read_log_event(log, packet))
{ {
case 0: case 0:
...@@ -300,7 +300,7 @@ void mysql_binlog_send(THD* thd, char* log_ident, ulong pos, ushort flags) ...@@ -300,7 +300,7 @@ void mysql_binlog_send(THD* thd, char* log_ident, ulong pos, ushort flags)
} }
pthread_mutex_unlock(log_lock); pthread_mutex_unlock(log_lock);
pthread_mutex_lock(&thd->mysys_var->mutex); pthread_mutex_lock(&thd->mysys_var->mutex);
thd->mysys_var->current_mutex= 0; thd->mysys_var->current_mutex= 0;
thd->mysys_var->current_cond= 0; thd->mysys_var->current_cond= 0;
...@@ -314,7 +314,7 @@ void mysql_binlog_send(THD* thd, char* log_ident, ulong pos, ushort flags) ...@@ -314,7 +314,7 @@ void mysql_binlog_send(THD* thd, char* log_ident, ulong pos, ushort flags)
errmsg = "Failed on my_net_write()"; errmsg = "Failed on my_net_write()";
goto err; goto err;
} }
if((*packet)[LOG_EVENT_OFFSET+1] == LOAD_EVENT) if((*packet)[LOG_EVENT_OFFSET+1] == LOAD_EVENT)
{ {
if(send_file(thd)) if(send_file(thd))
...@@ -334,14 +334,14 @@ void mysql_binlog_send(THD* thd, char* log_ident, ulong pos, ushort flags) ...@@ -334,14 +334,14 @@ void mysql_binlog_send(THD* thd, char* log_ident, ulong pos, ushort flags)
errmsg = "error reading log entry"; errmsg = "error reading log entry";
goto err; goto err;
} }
clearerr(log); clearerr(log);
} }
} }
else else
{ {
bool loop_breaker = 0; // need this to break out of the for loop from switch bool loop_breaker = 0; // need this to break out of the for loop from switch
switch(mysql_bin_log.find_next_log(&linfo)) switch(mysql_bin_log.find_next_log(&linfo))
{ {
case LOG_INFO_EOF: case LOG_INFO_EOF:
...@@ -367,12 +367,12 @@ void mysql_binlog_send(THD* thd, char* log_ident, ulong pos, ushort flags) ...@@ -367,12 +367,12 @@ void mysql_binlog_send(THD* thd, char* log_ident, ulong pos, ushort flags)
char header[9]; char header[9];
memset(header, 0, 4); // when does not matter memset(header, 0, 4); // when does not matter
header[4] = ROTATE_EVENT; header[4] = ROTATE_EVENT;
char* p = strrchr(log_file_name, FN_LIBCHAR); // find the last slash char* p = strrchr(log_file_name, FN_LIBCHAR); // find the last slash
if(p) if(p)
p++; p++;
else else
p = log_file_name; p = log_file_name;
uint ident_len = (uint) strlen(p); uint ident_len = (uint) strlen(p);
ulong event_len = ident_len + sizeof(header); ulong event_len = ident_len + sizeof(header);
int4store(header + 5, event_len); int4store(header + 5, event_len);
...@@ -388,9 +388,9 @@ void mysql_binlog_send(THD* thd, char* log_ident, ulong pos, ushort flags) ...@@ -388,9 +388,9 @@ void mysql_binlog_send(THD* thd, char* log_ident, ulong pos, ushort flags)
} }
} }
} }
(void)my_fclose(log, MYF(MY_WME)); (void)my_fclose(log, MYF(MY_WME));
send_eof(&thd->net); send_eof(&thd->net);
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
err: err:
...@@ -646,7 +646,7 @@ void close_thread_tables(THD *thd, bool locked) ...@@ -646,7 +646,7 @@ void close_thread_tables(THD *thd, bool locked)
VOID(pthread_mutex_lock(&LOCK_open)); VOID(pthread_mutex_lock(&LOCK_open));
DBUG_PRINT("info", ("thd->open_tables=%p", thd->open_tables)); DBUG_PRINT("info", ("thd->open_tables=%p", thd->open_tables));
for (table=thd->open_tables ; table ; table=next) for (table=thd->open_tables ; table ; table=next)
{ {
next=table->next; next=table->next;
...@@ -820,7 +820,7 @@ TABLE *unlink_open_table(THD *thd, TABLE *list, TABLE *find) ...@@ -820,7 +820,7 @@ TABLE *unlink_open_table(THD *thd, TABLE *list, TABLE *find)
} }
/* /*
When we call the following function we must have a lock on When we call the following function we must have a lock on
LOCK_OPEN ; This lock will be unlocked on return. LOCK_OPEN ; This lock will be unlocked on return.
*/ */
...@@ -957,7 +957,7 @@ TABLE *open_table(THD *thd,const char *db,const char *table_name, ...@@ -957,7 +957,7 @@ TABLE *open_table(THD *thd,const char *db,const char *table_name,
{ {
MEM_ROOT* glob_alloc; MEM_ROOT* glob_alloc;
LINT_INIT(glob_alloc); LINT_INIT(glob_alloc);
if(errno == ENOENT && if(errno == ENOENT &&
(glob_alloc = my_pthread_getspecific_ptr(MEM_ROOT*,THR_MALLOC))) (glob_alloc = my_pthread_getspecific_ptr(MEM_ROOT*,THR_MALLOC)))
// Sasha: needed for replication // Sasha: needed for replication
...@@ -1288,7 +1288,7 @@ bool wait_for_tables(THD *thd) ...@@ -1288,7 +1288,7 @@ bool wait_for_tables(THD *thd)
while (table_is_used(thd->open_tables) && ! thd->killed) while (table_is_used(thd->open_tables) && ! thd->killed)
{ {
(void) pthread_cond_wait(&COND_refresh,&LOCK_open); (void) pthread_cond_wait(&COND_refresh,&LOCK_open);
} }
if (thd->killed) if (thd->killed)
...@@ -1298,7 +1298,7 @@ bool wait_for_tables(THD *thd) ...@@ -1298,7 +1298,7 @@ bool wait_for_tables(THD *thd)
/* Now we can open all tables without any interference */ /* Now we can open all tables without any interference */
thd->proc_info="Reopen tables"; thd->proc_info="Reopen tables";
result=reopen_tables(thd,0,0); result=reopen_tables(thd,0,0);
} }
pthread_mutex_unlock(&LOCK_open); pthread_mutex_unlock(&LOCK_open);
thd->proc_info=0; thd->proc_info=0;
DBUG_RETURN(result); DBUG_RETURN(result);
...@@ -1744,7 +1744,7 @@ find_item_in_list(Item *find,List<Item> &items) ...@@ -1744,7 +1744,7 @@ find_item_in_list(Item *find,List<Item> &items)
} }
} }
} }
else if (!table_name && (item->eq(find) || else if (!table_name && (item->eq(find) ||
find->name && find->name &&
!my_strcasecmp(item->name,find->name))) !my_strcasecmp(item->name,find->name)))
{ {
...@@ -1824,7 +1824,7 @@ int setup_fields(THD *thd, TABLE_LIST *tables, List<Item> &fields, ...@@ -1824,7 +1824,7 @@ int setup_fields(THD *thd, TABLE_LIST *tables, List<Item> &fields,
} }
DBUG_RETURN(test(thd->fatal_error)); DBUG_RETURN(test(thd->fatal_error));
} }
static key_map get_key_map_from_key_list(THD *thd, TABLE *table, static key_map get_key_map_from_key_list(THD *thd, TABLE *table,
List<String> *index_list) List<String> *index_list)
...@@ -2172,18 +2172,22 @@ bool remove_table_from_cache(THD *thd, const char *db,const char *table_name) ...@@ -2172,18 +2172,22 @@ bool remove_table_from_cache(THD *thd, const char *db,const char *table_name)
DBUG_RETURN(result); DBUG_RETURN(result);
} }
/*
Will be used for ft-query optimization someday.
SerG.
*/
int setup_ftfuncs(THD *thd,TABLE_LIST *tables, List<Item_func_match> &ftfuncs) int setup_ftfuncs(THD *thd,TABLE_LIST *tables, List<Item_func_match> &ftfuncs)
{ {
List_iterator<Item_func_match> li(ftfuncs); List_iterator<Item_func_match> li(ftfuncs), li2(ftfuncs);
Item_func_match *ftf; Item_func_match *ftf, *ftf2;
while ((ftf=li++)) while ((ftf=li++))
{
if (ftf->fix_index()) if (ftf->fix_index())
return 1; return 1;
li2.rewind();
while ((ftf2=li2++) != ftf)
{
if (ftf->eq(ftf2) && !ftf2->master)
ftf2->master=ftf;
}
}
return 0; return 0;
} }
...@@ -1284,11 +1284,11 @@ add_ft_keys(DYNAMIC_ARRAY *keyuse_array, ...@@ -1284,11 +1284,11 @@ add_ft_keys(DYNAMIC_ARRAY *keyuse_array,
KEYUSE keyuse; KEYUSE keyuse;
keyuse.table= cond_func->table; keyuse.table= cond_func->table;
keyuse.val = cond_func->key_item(); keyuse.val = cond_func;
keyuse.key = cond_func->key; keyuse.key = cond_func->key;
#define FT_KEYPART (MAX_REF_PARTS+10) #define FT_KEYPART (MAX_REF_PARTS+10)
keyuse.keypart=FT_KEYPART; keyuse.keypart=FT_KEYPART;
keyuse.used_tables=keyuse.val->used_tables(); keyuse.used_tables=cond_func->key_item()->used_tables();
VOID(insert_dynamic(keyuse_array,(gptr) &keyuse)); VOID(insert_dynamic(keyuse_array,(gptr) &keyuse));
} }
...@@ -1670,7 +1670,7 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count, ...@@ -1670,7 +1670,7 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count,
else else
tmp=best_time; // Do nothing tmp=best_time; // Do nothing
} }
} /* not ftkey */ } /* not ft_key */
if (tmp < best_time - records/(double) TIME_FOR_COMPARE) if (tmp < best_time - records/(double) TIME_FOR_COMPARE)
{ {
best_time=tmp + records/(double) TIME_FOR_COMPARE; best_time=tmp + records/(double) TIME_FOR_COMPARE;
...@@ -1882,26 +1882,29 @@ get_best_combination(JOIN *join) ...@@ -1882,26 +1882,29 @@ get_best_combination(JOIN *join)
keyinfo=table->key_info+key; keyinfo=table->key_info+key;
if (ftkey) if (ftkey)
{ {
ft_tmp=keyuse->val->val_str(&tmp2); Item_func_match *ifm=(Item_func_match *)keyuse->val;
ft_tmp=ifm->key_item()->val_str(&tmp2);
length=ft_tmp->length(); length=ft_tmp->length();
keyparts=1; keyparts=1;
ifm->join_key=1;
} }
else else
{ {
keyparts=length=0; keyparts=length=0;
do do
{ {
if (!((~used_tables) & keyuse->used_tables)) if (!((~used_tables) & keyuse->used_tables))
{ {
if (keyparts == keyuse->keypart) if (keyparts == keyuse->keypart)
{ {
keyparts++; keyparts++;
length+=keyinfo->key_part[keyuse->keypart].length + length+=keyinfo->key_part[keyuse->keypart].length +
test(keyinfo->key_part[keyuse->keypart].null_bit); test(keyinfo->key_part[keyuse->keypart].null_bit);
} }
} }
keyuse++; keyuse++;
} while (keyuse->table == table && keyuse->key == key); } while (keyuse->table == table && keyuse->key == key);
} /* not ftkey */ } /* not ftkey */
/* set up fieldref */ /* set up fieldref */
...@@ -1924,7 +1927,7 @@ get_best_combination(JOIN *join) ...@@ -1924,7 +1927,7 @@ get_best_combination(JOIN *join)
byte *key_buff=j->ref.key_buff; byte *key_buff=j->ref.key_buff;
if (ftkey) if (ftkey)
{ {
j->ref.items[0]=keyuse->val; j->ref.items[0]=((Item_func*)(keyuse->val))->key_item();
if (!keyuse->used_tables && if (!keyuse->used_tables &&
!(join->select_options & SELECT_DESCRIBE)) !(join->select_options & SELECT_DESCRIBE))
{ {
......
...@@ -137,7 +137,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); ...@@ -137,7 +137,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token CHANGED_FILES %token CHANGED_FILES
%token CHECKSUM_SYM %token CHECKSUM_SYM
%token CHECK_SYM %token CHECK_SYM
%token COLLECTION
%token COLUMNS %token COLUMNS
%token COLUMN_SYM %token COLUMN_SYM
%token CONSTRAINT %token CONSTRAINT
...@@ -162,6 +161,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); ...@@ -162,6 +161,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token FOREIGN %token FOREIGN
%token FROM %token FROM
%token FULL %token FULL
%token FULLTEXT_SYM
%token GRANT %token GRANT
%token GRANTS %token GRANTS
%token GREATEST_SYM %token GREATEST_SYM
...@@ -457,7 +457,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); ...@@ -457,7 +457,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
expr_list udf_expr_list when_list ident_list expr_list udf_expr_list when_list ident_list
%type <key_type> %type <key_type>
key_type opt_unique key_type opt_unique_or_fulltext
%type <string_list> %type <string_list>
key_usage_list key_usage_list
...@@ -628,7 +628,7 @@ create: ...@@ -628,7 +628,7 @@ create:
} }
create2 create2
| CREATE opt_unique INDEX ident ON table_ident | CREATE opt_unique_or_fulltext INDEX ident ON table_ident
{ {
Lex->sql_command= SQLCOM_CREATE_INDEX; Lex->sql_command= SQLCOM_CREATE_INDEX;
if (!add_table_to_list($6,NULL)) if (!add_table_to_list($6,NULL))
...@@ -643,21 +643,6 @@ create: ...@@ -643,21 +643,6 @@ create:
Lex->key_list.push_back(new Key($2,$4.str,Lex->col_list)); Lex->key_list.push_back(new Key($2,$4.str,Lex->col_list));
Lex->col_list.empty(); Lex->col_list.empty();
} }
| CREATE COLLECTION ident ON table_ident
{
Lex->sql_command= SQLCOM_CREATE_INDEX;
if (!add_table_to_list($5,NULL))
YYABORT;
Lex->create_list.empty();
Lex->key_list.empty();
Lex->col_list.empty();
Lex->change=NullS;
}
'(' key_list ')'
{
Lex->key_list.push_back(new Key(Key::FULLTEXT,$3.str,Lex->col_list));
Lex->col_list.empty();
}
| CREATE DATABASE opt_if_not_exists ident | CREATE DATABASE opt_if_not_exists ident
{ {
Lex->sql_command=SQLCOM_CREATE_DB; Lex->sql_command=SQLCOM_CREATE_DB;
...@@ -964,7 +949,8 @@ delete_option: ...@@ -964,7 +949,8 @@ delete_option:
key_type: key_type:
opt_constraint PRIMARY_SYM KEY_SYM { $$= Key::PRIMARY; } opt_constraint PRIMARY_SYM KEY_SYM { $$= Key::PRIMARY; }
| key_or_index { $$= Key::MULTIPLE; } | key_or_index { $$= Key::MULTIPLE; }
| COLLECTION { $$= Key::FULLTEXT; } | FULLTEXT_SYM { $$= Key::FULLTEXT; }
| FULLTEXT_SYM key_or_index { $$= Key::FULLTEXT; }
| opt_constraint UNIQUE_SYM { $$= Key::UNIQUE; } | opt_constraint UNIQUE_SYM { $$= Key::UNIQUE; }
| opt_constraint UNIQUE_SYM key_or_index { $$= Key::UNIQUE; } | opt_constraint UNIQUE_SYM key_or_index { $$= Key::UNIQUE; }
...@@ -976,9 +962,10 @@ keys_or_index: ...@@ -976,9 +962,10 @@ keys_or_index:
KEYS {} KEYS {}
| INDEX {} | INDEX {}
opt_unique: opt_unique_or_fulltext:
/* empty */ { $$= Key::MULTIPLE; } /* empty */ { $$= Key::MULTIPLE; }
| UNIQUE_SYM { $$= Key::UNIQUE; } | UNIQUE_SYM { $$= Key::UNIQUE; }
| FULLTEXT_SYM { $$= Key::FULLTEXT; }
key_list: key_list:
key_list ',' key_part order_dir { Lex->col_list.push_back($3); } key_list ',' key_part order_dir { Lex->col_list.push_back($3); }
...@@ -2443,7 +2430,6 @@ keyword: ...@@ -2443,7 +2430,6 @@ keyword:
| WORK_SYM {} | WORK_SYM {}
| YEAR_SYM {} | YEAR_SYM {}
| SLAVE {} | SLAVE {}
| COLLECTION {}
/* Option functions */ /* Option functions */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment