Commit 44bc3f9b authored by sasha@mysql.sashanet.com's avatar sasha@mysql.sashanet.com

merge of conflicts

parents 0a087649 5d138848
......@@ -28,6 +28,8 @@ all: $(targets) txt_files
txt_files: ../INSTALL-SOURCE ../COPYING ../COPYING.LIB \
../MIRRORS INSTALL-BINARY
CLEAN_FILES: manual.ps
# The PostScript version is so big that is not included in the
# standard distribution. It is available for download from the home page.
paper: manual_a4.ps manual_letter.ps
......
This diff is collapsed.
......@@ -27,10 +27,14 @@ SUBDIRS = include @docs_dirs@ @readline_dir@ \
@bench_dirs@ support-files
# Relink after clean
CLEANFILES = linked_client_sources linked_server_sources linked_libmysql_sources linked_libmysql_r_sources
CLEANFILES = linked_client_sources linked_server_sources linked_libmysql_sources linked_libmysql_r_sources linked_include_sources
# This is just so that the linking is done early.
config.h: linked_client_sources linked_server_sources
config.h: linked_include_sources linked_client_sources linked_server_sources
linked_include_sources:
cd include; $(MAKE) link_sources
echo timestamp > linked_include_sources
linked_client_sources: @linked_client_targets@
echo timestamp > linked_client_sources
......
......@@ -17,7 +17,7 @@
/* Return error-text for system error messages and nisam messages */
#define PERROR_VERSION "2.2"
#define PERROR_VERSION "2.3"
#include <global.h>
#include <my_sys.h>
......@@ -59,9 +59,11 @@ static HA_ERRORS ha_errlist[]=
{ 136,"No more room in index file" },
{ 137,"No more records (read after end of file)" },
{ 138,"Unsupported extension used for table" },
{ 139,"Too big row (>= 24 M)"},
{ 139,"Too big row (>= 16 M)"},
{ 140,"Wrong create options"},
{ 141,"Dupplicate unique on write or update"},
{ 141,"Duplicate unique on write or update"},
{ 142,"Unknown character set used"},
{ 143,"Conflicting table definition between MERGE and mapped table"},
{ 0,NullS },
};
......
......@@ -15,11 +15,11 @@
# Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
# MA 02111-1307, USA
BUILT_SOURCES = my_config.h mysql_version.h m_ctype.h
BUILT_SOURCES = mysql_version.h m_ctype.h
pkginclude_HEADERS = dbug.h m_string.h my_sys.h mysql.h mysql_com.h \
mysqld_error.h my_list.h \
my_pthread.h my_no_pthread.h raid.h errmsg.h \
my_config.h my_global.h my_net.h \
my_global.h my_net.h \
sslopt-case.h sslopt-longopts.h sslopt-usage.h \
sslopt-vars.h $(BUILT_SOURCES)
noinst_HEADERS = global.h config-win.h \
......@@ -30,17 +30,19 @@ noinst_HEADERS = global.h config-win.h \
my_tree.h hash.h thr_alarm.h thr_lock.h \
getopt.h t_ctype.h violite.h \
mysql_version.h.in
EXTRA_DIST= my_config.h
# mysql_version.h are generated
SUPERCLEANFILES = mysql_version.h
SUPERCLEANFILES = mysql_version.h my_global.h
# Some include files that may be moved and patched by configure
DISTCLEANFILES = sched.h
CLEANFILES = my_config.h
all-local: my_config.h my_global.h
all-local: my_global.h
# Since we include my_config.h it better exist from the beginning
my_config.h: ../config.h
link_sources:
$(CP) ../config.h my_config.h
# This should be changed in the source and removed.
......
......@@ -83,7 +83,8 @@ extern int myrg_rsame(MYRG_INFO *file,byte *record,int inx);
extern int myrg_update(MYRG_INFO *file,const byte *old,byte *new_rec);
extern int myrg_status(MYRG_INFO *file,MYMERGE_INFO *x,int flag);
extern int myrg_lock_database(MYRG_INFO *file,int lock_type);
extern int myrg_create(const char *name,const char **table_names);
extern int myrg_create(const char *name,const char **table_names,
my_bool fix_names);
extern int myrg_extra(MYRG_INFO *file,enum ha_extra_function function);
extern ha_rows myrg_records_in_range(MYRG_INFO *info,int inx,
const byte *start_key,uint start_key_len,
......
......@@ -53,6 +53,7 @@ void delete_queue(QUEUE *queue);
void queue_insert(QUEUE *queue,byte *element);
byte *queue_remove(QUEUE *queue,uint idx);
void _downheap(QUEUE *queue,uint idx);
#define is_queue_inited(queue) ((queue)->root != 0)
#ifdef __cplusplus
}
......
......@@ -246,7 +246,7 @@ register char ***argv;
/* Fall through */
case 'I':
case '?':
printf("%s Ver 3.1 for %s at %s\n",my_progname,SYSTEM_TYPE,
printf("%s Ver 3.2 for %s at %s\n",my_progname,SYSTEM_TYPE,
MACHINE_TYPE);
puts("TCX Datakonsult AB, by Monty, for your professional use\n");
if (version)
......@@ -325,7 +325,7 @@ static int examine_log(my_string file_name, char **table_names)
init_io_cache(&cache,file,0,READ_CACHE,start_offset,0,MYF(0));
bzero((gptr) com_count,sizeof(com_count));
init_tree(&tree,0,sizeof(file_info),(qsort_cmp) file_info_compare,0,
init_tree(&tree,0,sizeof(file_info),(qsort_cmp) file_info_compare,1,
(void(*)(void*)) file_info_free);
VOID(init_key_cache(KEY_CACHE_SIZE,(uint) (10*4*(IO_SIZE+MALLOC_OVERHEAD))));
......
......@@ -75,7 +75,7 @@ clean-local:
rm -f `echo $(mystringsobjects) | sed "s;\.lo;.c;g"` \
`echo $(dbugobjects) | sed "s;\.lo;.c;g"` \
`echo $(mysysobjects) | sed "s;\.lo;.c;g"` \
$(mystringsextra) ctype_extra_sources.c \
$(mystringsextra) $(mysysheaders) ctype_extra_sources.c \
../linked_client_sources
ctype_extra_sources.c: conf_to_src
......
......@@ -69,7 +69,8 @@ int mi_log(int activate_log)
/* Logging of records and commands on logfile */
/* All logs starts with command(1) dfile(2) process(4) result(2) */
void _myisam_log(enum myisam_log_commands command, MI_INFO *info, const byte *buffert, uint length)
void _myisam_log(enum myisam_log_commands command, MI_INFO *info,
const byte *buffert, uint length)
{
char buff[11];
int error,old_errno;
......
......@@ -524,7 +524,11 @@ MI_INFO *mi_open(const char *name, int mode, uint handle_locking)
myisam_open_list=list_add(myisam_open_list,&m_info->open_list);
pthread_mutex_unlock(&THR_LOCK_myisam);
myisam_log(MI_LOG_OPEN,m_info,share->filename,(uint) strlen(share->filename));
if (myisam_log_file >= 0)
{
intern_filename(name_buff,share->filename);
_myisam_log(MI_LOG_OPEN,m_info,name_buff,(uint) strlen(name_buff));
}
DBUG_RETURN(m_info);
err:
......
......@@ -70,7 +70,7 @@ static void printf_log(const char *str,...);
static bool cmp_filename(struct file_info *file_info,my_string name);
static uint verbose=0,update=0,test_info=0,max_files=0,re_open_count=0,
recover=0,prefix_remove=0;
recover=0,prefix_remove=0,opt_processes=0;
static my_string log_filename=0,filepath=0,write_filename=0,record_pos_file=0;
static ulong com_count[10][3],number_of_commands=(ulong) ~0L,
isamlog_process;
......@@ -199,6 +199,9 @@ static void get_options(register int *argc, register char ***argv)
update=1;
recover++;
break;
case 'P':
opt_processes=1;
break;
case 'R':
if (! *++pos)
{
......@@ -243,7 +246,7 @@ static void get_options(register int *argc, register char ***argv)
/* Fall through */
case 'I':
case '?':
printf("%s Ver 1.1 for %s at %s\n",my_progname,SYSTEM_TYPE,
printf("%s Ver 1.2 for %s at %s\n",my_progname,SYSTEM_TYPE,
MACHINE_TYPE);
puts("By Monty, for your professional use\n");
if (version)
......@@ -258,6 +261,7 @@ static void get_options(register int *argc, register char ***argv)
puts(" -o \"offset\" -p # \"remove # components from path\"");
puts(" -r \"recover\" -R \"file recordposition\"");
puts(" -u \"update\" -v \"verbose\" -w \"write file\"");
puts(" -P \"processes\"");
puts("\nOne can give a second and a third '-v' for more verbose.");
puts("Normaly one does a update (-u).");
puts("If a recover is done all writes and all possibly updates and deletes is done\nand errors are only counted.");
......@@ -322,7 +326,7 @@ static int examine_log(my_string file_name, char **table_names)
init_io_cache(&cache,file,0,READ_CACHE,start_offset,0,MYF(0));
bzero((gptr) com_count,sizeof(com_count));
init_tree(&tree,0,sizeof(file_info),(qsort_cmp) file_info_compare,0,
init_tree(&tree,0,sizeof(file_info),(qsort_cmp) file_info_compare,1,
(void(*)(void*)) file_info_free);
VOID(init_key_cache(KEY_CACHE_SIZE,(uint) (10*4*(IO_SIZE+MALLOC_OVERHEAD))));
......@@ -333,6 +337,8 @@ static int examine_log(my_string file_name, char **table_names)
isamlog_filepos=my_b_tell(&cache)-9L;
file_info.filenr= mi_uint2korr(head+1);
isamlog_process=file_info.process=(long) mi_uint4korr(head+3);
if (!opt_processes)
file_info.process=0;
result= mi_uint2korr(head+7);
if ((curr_file_info=(struct file_info*) tree_search(&tree,&file_info)))
{
......@@ -374,11 +380,17 @@ static int examine_log(my_string file_name, char **table_names)
goto err;
{
uint i;
char *pos=file_info.name,*to;
char *pos,*to;
/* Fix if old DOS files to new format */
for (pos=file_info.name; pos=strchr(pos,'\\') ; pos++)
*pos= '/';
pos=file_info.name;
for (i=0 ; i < prefix_remove ; i++)
{
char *next;
if (!(next=strchr(pos,FN_LIBCHAR)))
if (!(next=strchr(pos,'/')))
break;
pos=next+1;
}
......@@ -436,7 +448,7 @@ static int examine_log(my_string file_name, char **table_names)
if (file_info.used)
{
if (verbose && !record_pos_file)
printf_log("%s: open",file_info.show_name);
printf_log("%s: open -> %d",file_info.show_name, file_info.filenr);
com_count[command][0]++;
if (result)
com_count[command][1]++;
......
......@@ -29,4 +29,4 @@ extern pthread_mutex_t THR_LOCK_open;
#endif
int _myrg_init_queue(MYRG_INFO *info,int inx,enum ha_rkey_function search_flag);
int _myrg_finish_scan(MYRG_INFO *info, int inx, enum ha_rkey_function type);
......@@ -23,8 +23,7 @@
a NULL-pointer last
*/
int myrg_create(name,table_names)
const char *name,**table_names;
int myrg_create(const char *name, const char **table_names, my_bool fix_names)
{
int save_errno;
uint errpos;
......@@ -38,15 +37,19 @@ const char *name,**table_names;
goto err;
errpos=1;
if (table_names)
{
for ( ; *table_names ; table_names++)
{
strmov(buff,*table_names);
fn_same(buff,name,4);
if (fix_names)
fn_same(buff,name,4);
*(end=strend(buff))='\n';
if (my_write(file,*table_names,(uint) (end-buff+1),
end[1]=0;
if (my_write(file,buff,(uint) (end-buff+1),
MYF(MY_WME | MY_NABP)))
goto err;
}
}
if (my_close(file,MYF(0)))
goto err;
DBUG_RETURN(0);
......
......@@ -58,7 +58,7 @@ int handle_locking;
{
if ((end=strend(buff))[-1] == '\n')
end[-1]='\0';
if (buff[0]) /* Skipp empty lines */
if (buff[0] && buff[0] != '#') /* Skipp empty lines and comments */
{
last_isam=isam;
if (!test_if_hard_path(buff))
......@@ -93,7 +93,7 @@ int handle_locking;
m_info->options|=isam->s->options;
m_info->records+=isam->state->records;
m_info->del+=isam->state->del;
m_info->data_file_length=isam->state->data_file_length;
m_info->data_file_length+=isam->state->data_file_length;
if (i)
isam=(MI_INFO*) (isam->open_list.next->data);
}
......
......@@ -23,31 +23,32 @@ static int queue_key_cmp(void *keyseg, byte *a, byte *b)
MI_INFO *aa=((MYRG_TABLE *)a)->table;
MI_INFO *bb=((MYRG_TABLE *)b)->table;
uint not_used;
return (_mi_key_cmp((MI_KEYSEG *)keyseg, aa->lastkey, bb->lastkey,
USE_WHOLE_KEY, SEARCH_FIND, &not_used));
int ret= _mi_key_cmp((MI_KEYSEG *)keyseg, aa->lastkey, bb->lastkey,
USE_WHOLE_KEY, SEARCH_FIND, &not_used);
return ret < 0 ? -1 : ret > 0 ? 1 : 0;
} /* queue_key_cmp */
int _myrg_init_queue(MYRG_INFO *info,int inx,enum ha_rkey_function search_flag)
{
QUEUE *q=&(info->by_key);
int error=0;
QUEUE *q= &(info->by_key);
if (!q->root)
if (!is_queue_inited(q))
{
if (init_queue(q,info->tables, 0,
(myisam_read_vec[search_flag]==SEARCH_SMALLER),
(myisam_readnext_vec[search_flag] == SEARCH_SMALLER),
queue_key_cmp,
info->open_tables->table->s->keyinfo[inx].seg))
return my_errno;
error=my_errno;
}
else
{
if (reinit_queue(q,info->tables, 0,
(myisam_read_vec[search_flag]==SEARCH_SMALLER),
(myisam_readnext_vec[search_flag] == SEARCH_SMALLER),
queue_key_cmp,
info->open_tables->table->s->keyinfo[inx].seg))
return my_errno;
error=my_errno;
}
return 0;
return error;
}
......@@ -16,7 +16,7 @@
#include "mymrgdef.h"
/* Read first row through a specfic key */
/* Read first row according to specific key */
int myrg_rfirst(MYRG_INFO *info, byte *buf, int inx)
{
......@@ -29,17 +29,17 @@ int myrg_rfirst(MYRG_INFO *info, byte *buf, int inx)
for (table=info->open_tables ; table < info->end_table ; table++)
{
err=mi_rfirst(table->table,NULL,inx);
info->last_used_table=table;
if (err == HA_ERR_END_OF_FILE)
continue;
if (err)
if ((err=mi_rfirst(table->table,NULL,inx)))
{
if (err == HA_ERR_END_OF_FILE)
continue;
return err;
}
/* adding to queue */
queue_insert(&(info->by_key),(byte *)table);
}
/* We have done a read in all tables */
info->last_used_table=table;
if (!info->by_key.elements)
return HA_ERR_END_OF_FILE;
......
......@@ -16,6 +16,17 @@
/* Read record based on a key */
/*
* HA_READ_KEY_EXACT => SEARCH_BIGGER
* HA_READ_KEY_OR_NEXT => SEARCH_BIGGER
* HA_READ_AFTER_KEY => SEARCH_BIGGER
* HA_READ_PREFIX => SEARCH_BIGGER
* HA_READ_KEY_OR_PREV => SEARCH_SMALLER
* HA_READ_BEFORE_KEY => SEARCH_SMALLER
* HA_READ_PREFIX_LAST => SEARCH_SMALLER
*/
#include "mymrgdef.h"
/* todo: we could store some additional info to speedup lookups:
......@@ -33,7 +44,7 @@ int myrg_rkey(MYRG_INFO *info,byte *record,int inx, const byte *key,
MYRG_TABLE *table;
MI_INFO *mi;
int err;
byte *buf=((search_flag == HA_READ_KEY_EXACT)?record:0);
byte *buf=((search_flag == HA_READ_KEY_EXACT) ? record: 0);
if (_myrg_init_queue(info,inx,search_flag))
return my_errno;
......@@ -52,13 +63,14 @@ int myrg_rkey(MYRG_INFO *info,byte *record,int inx, const byte *key,
{
err=_mi_rkey(mi,buf,inx,key_buff,pack_key_length,search_flag,FALSE);
}
info->last_used_table=table;
info->last_used_table=table+1;
if (err == HA_ERR_KEY_NOT_FOUND)
continue;
if (err)
{
if (err == HA_ERR_KEY_NOT_FOUND)
continue;
return err;
}
/* adding to queue */
queue_insert(&(info->by_key),(byte *)table);
......@@ -76,14 +88,3 @@ int myrg_rkey(MYRG_INFO *info,byte *record,int inx, const byte *key,
mi=(info->current_table=(MYRG_TABLE *)queue_top(&(info->by_key)))->table;
return mi_rrnd(mi,record,mi->lastpos);
}
/*
* HA_READ_KEY_EXACT => SEARCH_BIGGER
* HA_READ_KEY_OR_NEXT => SEARCH_BIGGER
* HA_READ_AFTER_KEY => SEARCH_BIGGER
* HA_READ_PREFIX => SEARCH_BIGGER
* HA_READ_KEY_OR_PREV => SEARCH_SMALLER
* HA_READ_BEFORE_KEY => SEARCH_SMALLER
* HA_READ_PREFIX_LAST => SEARCH_SMALLER
*/
......@@ -24,22 +24,22 @@ int myrg_rlast(MYRG_INFO *info, byte *buf, int inx)
MI_INFO *mi;
int err;
if (_myrg_init_queue(info,inx,HA_READ_KEY_OR_PREV))
if (_myrg_init_queue(info,inx, HA_READ_KEY_OR_PREV))
return my_errno;
for (table=info->open_tables ; table < info->end_table ; table++)
{
err=mi_rlast(table->table,NULL,inx);
info->last_used_table=table;
if (err == HA_ERR_END_OF_FILE)
continue;
if (err)
if ((err=mi_rlast(table->table,NULL,inx)))
{
if (err == HA_ERR_END_OF_FILE)
continue;
return err;
}
/* adding to queue */
queue_insert(&(info->by_key),(byte *)table);
}
/* We have done a read in all tables */
info->last_used_table=table;
if (!info->by_key.elements)
return HA_ERR_END_OF_FILE;
......
......@@ -22,22 +22,21 @@
int myrg_rnext(MYRG_INFO *info, byte *buf, int inx)
{
MYRG_TABLE *table;
MI_INFO *mi;
byte *key_buff;
uint pack_key_length;
int err;
MI_INFO *mi;
/* at first, do rnext for the table found before */
err=mi_rnext(info->current_table->table,NULL,inx);
if (err == HA_ERR_END_OF_FILE)
if ((err=mi_rnext(info->current_table->table,NULL,inx)))
{
queue_remove(&(info->by_key),0);
if (!info->by_key.elements)
return HA_ERR_END_OF_FILE;
if (err == HA_ERR_END_OF_FILE)
{
queue_remove(&(info->by_key),0);
if (!info->by_key.elements)
return HA_ERR_END_OF_FILE;
}
else
return err;
}
else if (err)
return err;
else
{
/* Found here, adding to queue */
......@@ -46,30 +45,42 @@ int myrg_rnext(MYRG_INFO *info, byte *buf, int inx)
}
/* next, let's finish myrg_rkey's initial scan */
table=info->last_used_table+1;
if ((err=_myrg_finish_scan(info, inx, HA_READ_KEY_OR_NEXT)))
return err;
/* now, mymerge's read_next is as simple as one queue_top */
mi=(info->current_table=(MYRG_TABLE *)queue_top(&(info->by_key)))->table;
return mi_rrnd(mi,buf,mi->lastpos);
}
/* let's finish myrg_rkey's initial scan */
int _myrg_finish_scan(MYRG_INFO *info, int inx, enum ha_rkey_function type)
{
int err;
MYRG_TABLE *table=info->last_used_table;
if (table < info->end_table)
{
mi=info->last_used_table->table;
key_buff=(byte*) mi->lastkey+mi->s->base.max_key_length;
pack_key_length=mi->last_rkey_length;
MI_INFO *mi= table[-1].table;
byte *key_buff=(byte*) mi->lastkey+mi->s->base.max_key_length;
uint pack_key_length= mi->last_rkey_length;
for (; table < info->end_table ; table++)
{
mi=table->table;
err=_mi_rkey(mi,NULL,inx,key_buff,pack_key_length,HA_READ_KEY_OR_NEXT,FALSE);
info->last_used_table=table;
if (err == HA_ERR_KEY_NOT_FOUND)
continue;
if (err)
return err;
if ((err=_mi_rkey(mi,NULL,inx,key_buff,pack_key_length,
type,FALSE)))
{
if (err == HA_ERR_KEY_NOT_FOUND) /* If end of file */
continue;
return err;
}
/* Found here, adding to queue */
queue_insert(&(info->by_key),(byte *)table);
queue_insert(&(info->by_key),(byte *) table);
}
/* All tables are now used */
info->last_used_table=table;
}
/* now, mymerge's read_next is as simple as one queue_top */
mi=(info->current_table=(MYRG_TABLE *)queue_top(&(info->by_key)))->table;
return mi_rrnd(mi,buf,mi->lastpos);
return 0;
}
......@@ -22,22 +22,21 @@
int myrg_rprev(MYRG_INFO *info, byte *buf, int inx)
{
MYRG_TABLE *table;
MI_INFO *mi;
byte *key_buff;
uint pack_key_length;
int err;
MI_INFO *mi;
/* at first, do rnext for the table found before */
err=mi_rprev(info->current_table->table,NULL,inx);
if (err == HA_ERR_END_OF_FILE)
/* at first, do rprev for the table found before */
if ((err=mi_rprev(info->current_table->table,NULL,inx)))
{
queue_remove(&(info->by_key),0);
if (!info->by_key.elements)
return HA_ERR_END_OF_FILE;
if (err == HA_ERR_END_OF_FILE)
{
queue_remove(&(info->by_key),0);
if (!info->by_key.elements)
return HA_ERR_END_OF_FILE;
}
else
return err;
}
else if (err)
return err;
else
{
/* Found here, adding to queue */
......@@ -46,28 +45,8 @@ int myrg_rprev(MYRG_INFO *info, byte *buf, int inx)
}
/* next, let's finish myrg_rkey's initial scan */
table=info->last_used_table+1;
if (table < info->end_table)
{
mi=info->last_used_table->table;
key_buff=(byte*) mi->lastkey+mi->s->base.max_key_length;
pack_key_length=mi->last_rkey_length;
for (; table < info->end_table ; table++)
{
mi=table->table;
err=_mi_rkey(mi,NULL,inx,key_buff,pack_key_length,
HA_READ_KEY_OR_PREV,FALSE);
info->last_used_table=table;
if (err == HA_ERR_KEY_NOT_FOUND)
continue;
if (err)
return err;
/* Found here, adding to queue */
queue_insert(&(info->by_key),(byte *)table);
}
}
if ((err=_myrg_finish_scan(info, inx, HA_READ_KEY_OR_PREV)))
return err;
/* now, mymerge's read_prev is as simple as one queue_top */
mi=(info->current_table=(MYRG_TABLE *)queue_top(&(info->by_key)))->table;
......
......@@ -84,10 +84,10 @@ int myrg_rrnd(MYRG_INFO *info,byte *buf,ulonglong filepos)
info->end_table-1,filepos);
isam_info=info->current_table->table;
isam_info->update&= HA_STATE_CHANGED;
return ((*isam_info->s->read_rnd)(isam_info,(byte*) buf,
(ha_rows) (filepos -
info->current_table->file_offset),
0));
return ((*isam_info->s->read_rnd)
(isam_info, (byte*) buf,
(ha_rows) (filepos - info->current_table->file_offset),
0));
}
......
No preview for this file type
......@@ -25,7 +25,7 @@
#include <queues.h>
/* The actuall code for handling queues */
/* Init queue */
int init_queue(QUEUE *queue, uint max_elements, uint offset_to_key,
pbool max_at_top, int (*compare) (void *, byte *, byte *),
......@@ -44,6 +44,12 @@ int init_queue(QUEUE *queue, uint max_elements, uint offset_to_key,
DBUG_RETURN(0);
}
/*
Reinitialize queue for new usage; Note that you can't currently resize
the number of elements! If you need this, fix it :)
*/
int reinit_queue(QUEUE *queue, uint max_elements, uint offset_to_key,
pbool max_at_top, int (*compare) (void *, byte *, byte *),
void *first_cmp_arg)
......@@ -78,6 +84,7 @@ void delete_queue(QUEUE *queue)
void queue_insert(register QUEUE *queue, byte *element)
{
reg2 uint idx,next;
int cmp;
#ifndef DBUG_OFF
if (queue->elements < queue->max_elements)
......@@ -86,10 +93,12 @@ void queue_insert(register QUEUE *queue, byte *element)
queue->root[0]=element;
idx= ++queue->elements;
while ((queue->compare(queue->first_cmp_arg,
element+queue->offset_to_key,
queue->root[(next=idx >> 1)]+queue->offset_to_key)
^ queue->max_at_top) < 0)
/* max_at_top swaps the comparison if we want to order by desc */
while ((cmp=queue->compare(queue->first_cmp_arg,
element+queue->offset_to_key,
queue->root[(next=idx >> 1)] +
queue->offset_to_key)) &&
(cmp ^ queue->max_at_top) < 0)
{
queue->root[idx]=queue->root[next];
idx=next;
......
......@@ -53,12 +53,14 @@ pkgdata_DATA = make_binary_distribution
CLEANFILES = @server_scripts@ \
make_binary_distribution \
msql2mysql \
mysql_config \
mysql_fix_privilege_tables \
mysql_setpermission \
mysql_zap \
mysqlaccess \
mysql_convert_table_format \
mysql_find_rows
mysql_find_rows \
mysqlhotcopy
SUPERCLEANFILES = mysqlbug
......
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
......@@ -348,12 +348,12 @@ print " for select_diff_key ($count:$rows): " .
# Test select that is very popular when using ODBC
check_or_range("id","select_range_prefix");
check_or_range("id3","select_range");
check_or_range("id3","select_range_key2");
# Check reading on direct key on id and id3
check_select_key("id","select_key_prefix");
check_select_key("id3","select_key");
check_select_key("id3","select_key_key2");
####
#### A lot of simple selects on ranges
......@@ -403,7 +403,7 @@ check_select_key("id3","select_key");
print "\nTest of compares with simple ranges\n";
check_select_range("id","select_range_prefix");
check_select_range("id3","select_range");
check_select_range("id3","select_range_key2");
####
#### Some group queries
......@@ -1107,20 +1107,28 @@ if ($server->small_rollback_segment())
# Delete everything from table
#
print "Deleting everything from table\n";
print "Deleting rows from the table\n";
$loop_time=new Benchmark;
$count=0;
for ($i=0 ; $i < 128 ; $i++)
{
$dbh->do("delete from bench1 where field1 = $i") or die $DBI::errstr;
}
$end_time=new Benchmark;
print "Time for delete_big_many_keys ($count): " .
timestr(timediff($end_time, $loop_time),"all") . "\n\n";
print "Deleting everything from table\n";
$count=1;
if ($opt_fast)
{
$dbh->do("delete from bench1 where field1 = 0") or die $DBI::errstr;
$dbh->do("delete from bench1") or die $DBI::errstr;
$count+=2;
}
else
{
$dbh->do("delete from bench1 where field1 = 0") or die $DBI::errstr;
$dbh->do("delete from bench1 where field1 > 0") or die $DBI::errstr;
$count+=2;
}
if ($opt_lock_tables)
......@@ -1129,7 +1137,7 @@ if ($opt_lock_tables)
}
$end_time=new Benchmark;
print "Time for delete_big_many_keys ($count): " .
print "Time for delete_all_many_keys ($count): " .
timestr(timediff($end_time, $loop_time),"all") . "\n\n";
$sth = $dbh->do("drop table bench1") or die $DBI::errstr;
......
......@@ -261,7 +261,7 @@ ha_rows ha_heap::records_in_range(int inx,
if (start_key_len != end_key_len ||
start_key_len != pos->key_length ||
start_search_flag != HA_READ_KEY_EXACT ||
end_search_flag != HA_READ_KEY_EXACT)
end_search_flag != HA_READ_AFTER_KEY)
return HA_POS_ERROR; // Can't only use exact keys
return 10; // Good guess
}
......
......@@ -33,14 +33,15 @@ class ha_heap: public handler
const char *table_type() const { return "HEAP"; }
const char **bas_ext() const;
ulong option_flag() const
{ return (HA_READ_RND_SAME+HA_NO_INDEX+HA_BINARY_KEYS+HA_WRONG_ASCII_ORDER+
HA_KEYPOS_TO_RNDPOS+HA_NO_BLOBS+HA_REC_NOT_IN_SEQ); }
{ return (HA_READ_RND_SAME | HA_NO_INDEX | HA_ONLY_WHOLE_INDEX |
HA_WRONG_ASCII_ORDER | HA_KEYPOS_TO_RNDPOS | HA_NO_BLOBS |
HA_REC_NOT_IN_SEQ); }
uint max_record_length() const { return HA_MAX_REC_LENGTH; }
uint max_keys() const { return MAX_KEY; }
uint max_key_parts() const { return MAX_REF_PARTS; }
uint max_key_length() const { return HA_MAX_REC_LENGTH; }
virtual double scan_time() { return (double) (records+deleted) / 100.0; }
virtual double read_time(ha_rows rows) { return (double) rows / 100.0; }
virtual double scan_time() { return (double) (records+deleted) / 20.0+10; }
virtual double read_time(ha_rows rows) { return (double) rows / 20.0+1; }
virtual bool fast_key_read() { return 1;}
int open(const char *name, int mode, int test_if_locked);
......
......@@ -45,7 +45,7 @@ class ha_myisam: public handler
const char **bas_ext() const;
ulong option_flag() const { return int_option_flag; }
uint max_record_length() const { return HA_MAX_REC_LENGTH; }
uint max_keys() const { return 1; }
uint max_keys() const { return MI_MAX_KEY; }
uint max_key_parts() const { return MAX_REF_PARTS; }
uint max_key_length() const { return MAX_KEY_LENGTH; }
......
......@@ -180,11 +180,7 @@ void ha_myisammrg::info(uint flag)
mean_rec_length=info.reclength;
block_size=0;
update_time=0;
#if SIZEOF_OFF_T > 4
ref_length=6; // Should be big enough
#else
ref_length=4;
#endif
}
......@@ -228,6 +224,16 @@ THR_LOCK_DATA **ha_myisammrg::store_lock(THD *thd,
int ha_myisammrg::create(const char *name, register TABLE *form,
HA_CREATE_INFO *create_info)
{
char buff[FN_REFLEN];
return myrg_create(fn_format(buff,name,"","",2+4+16),0);
char buff[FN_REFLEN],**table_names,**pos;
TABLE_LIST *tables= (TABLE_LIST*) create_info->merge_list.first;
DBUG_ENTER("ha_myisammrg::create");
if (!(table_names= (char**) sql_alloc((create_info->merge_list.elements+1)*
sizeof(char*))))
DBUG_RETURN(1);
for (pos=table_names ; tables ; tables=tables->next)
*pos++= tables->real_name;
*pos=0;
DBUG_RETURN(myrg_create(fn_format(buff,name,"","",2+4+16),
(const char **) table_names, (my_bool) 0));
}
......@@ -32,15 +32,19 @@ class ha_myisammrg: public handler
~ha_myisammrg() {}
const char *table_type() const { return "MRG_MyISAM"; }
const char **bas_ext() const;
ulong option_flag() const { return HA_REC_NOT_IN_SEQ+HA_READ_NEXT+
HA_READ_PREV+HA_READ_RND_SAME+HA_HAVE_KEY_READ_ONLY+
HA_KEYPOS_TO_RNDPOS+HA_READ_ORDER+
HA_LASTKEY_ORDER+HA_READ_NOT_EXACT_KEY+
HA_LONGLONG_KEYS+HA_NULL_KEY+HA_BLOB_KEY; }
ulong option_flag() const
{ return (HA_REC_NOT_IN_SEQ | HA_READ_NEXT |
HA_READ_PREV | HA_READ_RND_SAME |
HA_HAVE_KEY_READ_ONLY |
HA_KEYPOS_TO_RNDPOS | HA_READ_ORDER |
HA_LASTKEY_ORDER | HA_READ_NOT_EXACT_KEY |
HA_LONGLONG_KEYS | HA_NULL_KEY | HA_BLOB_KEY); }
uint max_record_length() const { return HA_MAX_REC_LENGTH; }
uint max_keys() const { return 1; }
uint max_keys() const { return MI_MAX_KEY; }
uint max_key_parts() const { return MAX_REF_PARTS; }
uint max_key_length() const { return MAX_KEY_LENGTH; }
virtual double scan_time()
{ return ulonglong2double(data_file_length) / IO_SIZE + file->tables; }
int open(const char *name, int mode, int test_if_locked);
int close(void);
......
......@@ -48,7 +48,7 @@
if database is updated after read) */
#define HA_REC_NOT_IN_SEQ 64 /* ha_info don't return recnumber;
It returns a position to ha_r_rnd */
#define HA_BINARY_KEYS 128 /* Keys must be exact */
#define HA_ONLY_WHOLE_INDEX 128 /* Can't use part key searches */
#define HA_RSAME_NO_INDEX 256 /* RSAME can't restore index */
#define HA_WRONG_ASCII_ORDER 512 /* Can't use sorting through key */
#define HA_HAVE_KEY_READ_ONLY 1024 /* Can read only keys (no record) */
......@@ -128,6 +128,7 @@ typedef struct st_ha_create_information
ulong raid_chunksize;
bool if_not_exists;
ulong used_fields;
SQL_LIST merge_list;
} HA_CREATE_INFO;
......
......@@ -299,11 +299,12 @@ static SYMBOL symbols[] = {
{ "TRAILING", SYM(TRAILING),0,0},
{ "TO", SYM(TO_SYM),0,0},
{ "TYPE", SYM(TYPE_SYM),0,0},
{ "USE", SYM(USE_SYM),0,0},
{ "USING", SYM(USING),0,0},
{ "UNION", SYM(UNION_SYM),0,0},
{ "UNIQUE", SYM(UNIQUE_SYM),0,0},
{ "UNLOCK", SYM(UNLOCK_SYM),0,0},
{ "UNSIGNED", SYM(UNSIGNED),0,0},
{ "USE", SYM(USE_SYM),0,0},
{ "USING", SYM(USING),0,0},
{ "UPDATE", SYM(UPDATE_SYM),0,0},
{ "USAGE", SYM(USAGE),0,0},
{ "VALUES", SYM(VALUES),0,0},
......
......@@ -78,7 +78,11 @@ void sql_element_free(void *ptr);
// The following is used to decide if MySQL should use table scanning
// instead of reading with keys. The number says how many evaluation of the
// WHERE clause is comparable to reading one extra row from a table.
#define TIME_FOR_COMPARE 5 // 5 compares == one read
#define TIME_FOR_COMPARE 5 // 5 compares == one read
// Number of rows in a reference table when refereed through a not unique key.
// This value is only used when we don't know anything about the key
// distribution.
#define MATCHING_ROWS_IN_OTHER_TABLE 10
/* Don't pack string keys shorter than this (if PACK_KEYS=1 isn't used) */
#define KEY_DEFAULT_PACK_LENGTH 8
......
......@@ -16,7 +16,7 @@ install-data-local:
$(DESTDIR)$(pkgdatadir)/$$lang/errmsg.txt; \
done
$(mkinstalldirs) $(DESTDIR)$(pkgdatadir)/charsets
(for f in Index README "*.conf"; \
(cd $(srcdir)/charsets; for f in Index README "*.conf"; \
do \
$(INSTALL_DATA) $(srcdir)/charsets/$$f $(DESTDIR)$(pkgdatadir)/charsets/; \
$(INSTALL_DATA) $$f $(DESTDIR)$(pkgdatadir)/charsets/; \
done)
......@@ -1905,6 +1905,7 @@ int grant_init (void)
{
t_table->file->index_end();
mysql_unlock_tables(thd, lock);
thd->version--; // Force close to free memory
close_thread_tables(thd);
delete thd;
DBUG_RETURN(0); // Empty table is ok!
......
......@@ -94,16 +94,9 @@ typedef struct st_lex {
LEX_YYSTYPE yylval;
uchar *ptr,*tok_start,*tok_end,*end_of_query;
ha_rows select_limit,offset_limit;
bool create_refs,drop_primary,drop_if_exists,local_file,
in_comment,ignore_space,verbose;
enum_sql_command sql_command;
enum lex_states next_state;
ulong options;
uint in_sum_expr,grant,grant_tot_col,which_columns, sort_default;
char *length,*dec,*change,*name;
String *wild;
sql_exchange *exchange;
thr_lock_type lock_option;
List<List_item> expr_list;
List<List_item> when_list;
......@@ -124,18 +117,25 @@ typedef struct st_lex {
create_field *last_field;
Item *where,*having,*default_value;
enum enum_duplicates duplicates;
ulong thread_id,type;
HA_CREATE_INFO create_info;
CONVERT *convert_set;
LEX_USER *grant_user;
LEX_USER *grant_user;
char *db,*db1,*table1,*db2,*table2; /* For outer join using .. */
gptr yacc_yyss,yacc_yyvs;
THD *thd;
udf_func udf;
HA_CHECK_OPT check_opt; // check/repair options
LEX_MASTER_INFO mi; // used by CHANGE MASTER
char* backup_dir; // used by BACKUP / RESTORE
HA_CHECK_OPT check_opt; // check/repair options
HA_CREATE_INFO create_info;
LEX_MASTER_INFO mi; // used by CHANGE MASTER
ulong thread_id,type;
ulong options;
enum_sql_command sql_command;
enum lex_states next_state;
enum enum_duplicates duplicates;
uint in_sum_expr,grant,grant_tot_col,which_columns, sort_default;
thr_lock_type lock_option;
bool create_refs,drop_primary,drop_if_exists,local_file;
bool in_comment,ignore_space,verbose;
} LEX;
......
......@@ -38,8 +38,9 @@ extern "C" pthread_mutex_t THR_LOCK_keycache;
extern "C" int gethostname(char *name, int namelen);
#endif
static bool check_table_access(THD *thd,uint want_access,TABLE_LIST *tables);
static bool check_table_access(THD *thd,uint want_access, TABLE_LIST *tables);
static bool check_db_used(THD *thd,TABLE_LIST *tables);
static bool check_merge_table_access(THD *thd, char *db, TABLE_LIST *tables);
static bool check_dup(THD *thd,const char *db,const char *name,
TABLE_LIST *tables);
static void mysql_init_query(THD *thd);
......@@ -504,9 +505,9 @@ int mysql_table_dump(THD* thd, char* db, char* tbl_name, int fd)
if(!(table=open_ltable(thd, table_list, TL_READ_NO_INSERT)))
DBUG_RETURN(1);
if(check_access(thd, SELECT_ACL, db, &table_list->grant.privilege))
if (check_access(thd, SELECT_ACL, db, &table_list->grant.privilege))
goto err;
if(grant_option && check_grant(thd, SELECT_ACL, table_list))
if (grant_option && check_grant(thd, SELECT_ACL, table_list))
goto err;
thd->free_list = 0;
......@@ -1007,10 +1008,12 @@ mysql_execute_command(void)
break;
case SQLCOM_CREATE_TABLE:
#ifdef DEMO_VERSION
send_error(&thd->net,ER_NOT_ALLOWED_COMMAND);
#else
if (check_access(thd,CREATE_ACL,tables->db,&tables->grant.privilege))
if (!tables->db)
tables->db=thd->db;
if (check_access(thd,CREATE_ACL,tables->db,&tables->grant.privilege) ||
check_merge_table_access(thd, tables->db,
(TABLE_LIST *)
lex->create_info.merge_list.first))
goto error; /* purecov: inspected */
if (grant_option)
{
......@@ -1091,7 +1094,6 @@ mysql_execute_command(void)
if (grant_option && check_grant(thd,INDEX_ACL,tables))
goto error;
res = mysql_create_index(thd, tables, lex->key_list);
#endif
break;
case SQLCOM_SLAVE_START:
......@@ -1101,7 +1103,6 @@ mysql_execute_command(void)
stop_slave(thd);
break;
case SQLCOM_ALTER_TABLE:
#if defined(DONT_ALLOW_SHOW_COMMANDS)
send_error(&thd->net,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */
......@@ -1115,11 +1116,16 @@ mysql_execute_command(void)
res=0;
break;
}
if (!tables->db)
tables->db=thd->db;
if (!lex->db)
lex->db=tables->db;
if (check_access(thd,ALTER_ACL,tables->db,&tables->grant.privilege) ||
check_access(thd,INSERT_ACL | CREATE_ACL,lex->db,&priv))
goto error; /* purecov: inspected */
check_access(thd,INSERT_ACL | CREATE_ACL,lex->db,&priv) ||
check_merge_table_access(thd, tables->db,
(TABLE_LIST *)
lex->create_info.merge_list.first))
goto error; /* purecov: inspected */
if (!tables->db)
tables->db=thd->db;
if (grant_option)
......@@ -1373,7 +1379,7 @@ mysql_execute_command(void)
res = mysql_drop_index(thd, tables, lex->drop_list);
break;
case SQLCOM_SHOW_DATABASES:
#if defined(DONT_ALLOW_SHOW_COMMANDS) || defined(DEMO_VERSION)
#if defined(DONT_ALLOW_SHOW_COMMANDS)
send_error(&thd->net,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */
DBUG_VOID_RETURN;
#else
......@@ -1829,6 +1835,22 @@ static bool check_db_used(THD *thd,TABLE_LIST *tables)
}
static bool check_merge_table_access(THD *thd, char *db, TABLE_LIST *table_list)
{
int error=0;
if (table_list)
{
/* Force all tables to use the current database */
TABLE_LIST *tmp;
for (tmp=table_list; tmp ; tmp=tmp->next)
tmp->db=db;
error=check_table_access(thd, SELECT_ACL | UPDATE_ACL | DELETE_ACL,
table_list);
}
return error;
}
/****************************************************************************
Check stack size; Send error if there isn't enough stack to continue
****************************************************************************/
......@@ -2481,7 +2503,7 @@ static int start_slave(THD* thd , bool net_report)
if(!thd) thd = current_thd;
NET* net = &thd->net;
const char* err = 0;
if(check_access(thd, PROCESS_ACL, any_db))
if (check_access(thd, PROCESS_ACL, any_db))
return 1;
pthread_mutex_lock(&LOCK_slave);
if(!slave_running)
......@@ -2516,7 +2538,7 @@ static int stop_slave(THD* thd, bool net_report )
NET* net = &thd->net;
const char* err = 0;
if(check_access(thd, PROCESS_ACL, any_db))
if (check_access(thd, PROCESS_ACL, any_db))
return 1;
pthread_mutex_lock(&LOCK_slave);
......
......@@ -942,7 +942,7 @@ make_join_statistics(JOIN *join,TABLE_LIST *tables,COND *conds,
}
/* Approximate found rows and time to read them */
s->found_records=s->records=s->table->file->records;
s->read_time=(ha_rows) ((s->table->file->data_file_length)/IO_SIZE)+1;
s->read_time=(ha_rows) s->table->file->scan_time();
/* Set a max range of how many seeks we can expect when using keys */
s->worst_seeks= (double) (s->read_time*2);
......@@ -1419,18 +1419,18 @@ update_ref_and_keys(DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab,uint tables,
for (i=0 ; i < keyuse->elements-1 ; i++,use++)
{
if (!use->used_tables)
use->table->const_key_parts[use->key]|=
use->table->const_key_parts[use->key] |=
(key_part_map) 1 << use->keypart;
if (use->keypart != FT_KEYPART)
{
if (use->key == prev->key && use->table == prev->table)
{
if (prev->keypart+1 < use->keypart ||
prev->keypart == use->keypart && found_eq_constant)
continue; /* remove */
}
else if (use->keypart != 0) // First found must be 0
continue;
if (use->key == prev->key && use->table == prev->table)
{
if (prev->keypart+1 < use->keypart ||
prev->keypart == use->keypart && found_eq_constant)
continue; /* remove */
}
else if (use->keypart != 0) // First found must be 0
continue;
}
*save_pos= *use;
......@@ -1532,7 +1532,7 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count,
double best_records=DBL_MAX;
/* Test how we can use keys */
rec= s->records/10; /* Assume 10 records/key */
rec= s->records/MATCHING_ROWS_IN_OTHER_TABLE; /* Assumed records/key */
for (keyuse=s->keyuse ; keyuse->table == table ;)
{
key_map found_part=0;
......@@ -1571,7 +1571,7 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count,
if (map == 1) // Only one table
{
TABLE *tmp_table=join->all_tables[tablenr];
if (rec > tmp_table->file->records)
if (rec > tmp_table->file->records && rec > 100)
rec=max(tmp_table->file->records,100);
}
}
......@@ -1615,12 +1615,12 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count,
}
else
{
if (!found_ref) // If not const key
{
if (!found_ref)
{ // We found a const key
if (table->quick_keys & ((key_map) 1 << key))
records= (double) table->quick_rows[key];
else
records= (double) s->records; // quick_range couldn't use key!
records= (double) s->records/rec; // quick_range couldn't use key!
}
else
{
......@@ -1654,7 +1654,8 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count,
** than a not unique key
** Set tmp to (previous record count) * (records / combination)
*/
if (found_part & 1)
if ((found_part & 1) &&
!(table->file->option_flag() & HA_ONLY_WHOLE_INDEX))
{
uint max_key_part=max_part_bit(found_part);
/* Check if quick_range could determinate how many rows we
......
......@@ -176,7 +176,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
DBUG_ENTER("mysql_create_table");
/*
** Check for dupplicate fields and check type of table to create
** Check for duplicate fields and check type of table to create
*/
if (!fields.elements)
......@@ -302,7 +302,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
bool primary_key=0,unique_key=0;
Key *key;
uint tmp;
tmp=max(file->max_keys(), MAX_KEY);
tmp=min(file->max_keys(), MAX_KEY);
if (key_count > tmp)
{
......
......@@ -264,6 +264,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token UDF_RETURNS_SYM
%token UDF_SONAME_SYM
%token UDF_SYM
%token UNION_SYM
%token UNIQUE_SYM
%token USAGE
%token USE_SYM
......@@ -716,6 +717,18 @@ create_table_option:
| RAID_TYPE EQ raid_types { Lex->create_info.raid_type= $3; Lex->create_info.used_fields|= HA_CREATE_USED_RAID;}
| RAID_CHUNKS EQ ULONG_NUM { Lex->create_info.raid_chunks= $3; Lex->create_info.used_fields|= HA_CREATE_USED_RAID;}
| RAID_CHUNKSIZE EQ ULONG_NUM { Lex->create_info.raid_chunksize= $3*RAID_BLOCK_SIZE; Lex->create_info.used_fields|= HA_CREATE_USED_RAID;}
| UNION_SYM EQ '(' table_list ')'
{
/* Move the union list to the merge_list */
LEX *lex=Lex;
TABLE_LIST *table_list= (TABLE_LIST*) lex->table_list.first;
lex->create_info.merge_list= lex->table_list;
lex->create_info.merge_list.elements--;
lex->create_info.merge_list.first= (byte*) (table_list->next);
lex->table_list.elements=1;
lex->table_list.next= (byte**) &(table_list->next);
table_list->next=0;
}
table_types:
ISAM_SYM { $$= DB_TYPE_ISAM; }
......
......@@ -41,7 +41,10 @@ CLEANFILES = my-small.cnf \
my-huge.cnf \
mysql.spec \
mysql-@VERSION@.spec \
mysql.server
mysql-log-rotate \
mysql.server \
binary-configure
mysql-@VERSION@.spec: mysql.spec
rm -f $@
......
File mode changed from 100755 to 100644
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