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

Merge work:/home/bk/mysql-4.0

into mysql.sashanet.com:/home/sasha/src/bk/mysql-4.0
parents 845fc9e0 e743944f
......@@ -44,7 +44,7 @@ void _hp_clear(HP_SHARE *info)
block->levels=0;
block->last_allocated=0;
}
info->records=info->deleted=info->data_length=info->index_length=0;;
info->records=info->deleted=info->data_length=info->index_length=0;
info->blength=1;
info->changed=0;
info->del_link=0;
......
......@@ -19,7 +19,7 @@
#include "heapdef.h"
/* Close a database open by hp_open() */
/* Data is not deallocated */
/* Data is normally not deallocated */
int heap_close(HP_INFO *info)
{
......@@ -43,8 +43,9 @@ int _hp_close(register HP_INFO *info)
}
#endif
info->s->changed=0;
info->s->open_count--;
heap_open_list=list_delete(heap_open_list,&info->open_list);
if (!--info->s->open_count && info->s->delete_on_close)
_hp_free(info->s); /* Table was deleted */
my_free((gptr) info,MYF(0));
DBUG_RETURN(error);
}
......
......@@ -21,33 +21,49 @@
#include "heapdef.h"
int heap_create(const char *name)
{
reg1 HP_SHARE *share;
DBUG_ENTER("heap_create");
(void) heap_delete_all(name);
pthread_mutex_lock(&THR_LOCK_heap);
if ((share=_hp_find_named_heap(name)))
{
if (share->open_count == 0)
_hp_free(share);
}
else
{
my_errno=ENOENT;
}
pthread_mutex_unlock(&THR_LOCK_heap);
DBUG_RETURN(0);
}
int heap_delete_all(const char *name)
int heap_delete_table(const char *name)
{
reg1 HP_SHARE *info;
int found;
DBUG_ENTER("heap_delete_all");
int result;
reg1 HP_SHARE *share;
DBUG_ENTER("heap_delete_table");
pthread_mutex_lock(&THR_LOCK_heap);
if ((info=_hp_find_named_heap(name)))
if ((share=_hp_find_named_heap(name)))
{
if (info->open_count == 0)
_hp_free(info);
found=0;
if (share->open_count == 0)
_hp_free(share);
else
share->delete_on_close=1;
result=0;
}
else
{
found=my_errno=ENOENT;
result=my_errno=ENOENT;
}
pthread_mutex_unlock(&THR_LOCK_heap);
DBUG_RETURN(found);
DBUG_RETURN(result);
}
void _hp_free(HP_SHARE *share)
{
heap_share_list=list_delete(heap_share_list,&share->open_list);
......
......@@ -50,7 +50,8 @@ int heap_delete(HP_INFO *info, const byte *record)
info->current_hash_ptr=0;
DBUG_RETURN(0);
err:
if( ++(share->records) == share->blength) share->blength+= share->blength;
if (++(share->records) == share->blength)
share->blength+= share->blength;
DBUG_RETURN(my_errno);
}
......@@ -66,7 +67,8 @@ int _hp_delete_key(HP_INFO *info, register HP_KEYDEF *keyinfo,
DBUG_ENTER("_hp_delete_key");
blength=share->blength;
if (share->records+1 == blength) blength+= blength;
if (share->records+1 == blength)
blength+= blength;
lastpos=hp_find_hash(&keyinfo->block,share->records);
last_ptr=0;
......
......@@ -574,7 +574,7 @@ char *argv[];
heap_clear(file);
if (heap_close(file) || (file2 && heap_close(file2)))
goto err;
heap_delete_all(filename2);
heap_delete_table(filename2);
heap_panic(HA_PANIC_CLOSE);
my_end(MY_GIVE_INFO);
return(0);
......
......@@ -109,6 +109,7 @@ typedef struct st_heap_share
THR_LOCK lock;
pthread_mutex_t intern_lock; /* Locking for use with _locking */
#endif
my_bool delete_on_close;
LIST open_list;
} HP_SHARE;
......@@ -144,7 +145,7 @@ extern int heap_scan(register HP_INFO *info, byte *record);
extern int heap_delete(HP_INFO *info,const byte *buff);
extern int heap_info(HP_INFO *info,HEAPINFO *x,int flag);
extern int heap_create(const char *name);
extern int heap_delete_all(const char *name);
extern int heap_delete_table(const char *name);
extern int heap_extra(HP_INFO *info,enum ha_extra_function function);
extern int heap_rename(const char *old_name,const char *new_name);
extern int heap_panic(enum ha_panic_function flag);
......
......@@ -93,7 +93,8 @@ enum ha_extra_function {
HA_EXTRA_NO_IGNORE_DUP_KEY,
HA_EXTRA_DONT_USE_CURSOR_TO_UPDATE, /* Cursor will not be used for update */
HA_EXTRA_BULK_INSERT_BEGIN,
HA_EXTRA_BULK_INSERT_END
HA_EXTRA_BULK_INSERT_END,
HA_EXTRA_PREPARE_FOR_DELETE
};
/* The following is parameter to ha_panic() */
......
......@@ -246,7 +246,8 @@ typedef struct st_record_cache /* Used when cacheing records */
} RECORD_CACHE;
enum file_type { UNOPEN = 0, FILE_BY_OPEN, FILE_BY_CREATE,
STREAM_BY_FOPEN, STREAM_BY_FDOPEN, FILE_BY_MKSTEMP };
STREAM_BY_FOPEN, STREAM_BY_FDOPEN, FILE_BY_MKSTEMP,
FILE_BY_DUP };
extern struct my_file_info
{
......@@ -387,6 +388,7 @@ extern File my_register_filename(File fd, const char *FileName,
extern File my_create(const char *FileName,int CreateFlags,
int AccsesFlags, myf MyFlags);
extern int my_close(File Filedes,myf MyFlags);
extern File my_dup(File file, myf MyFlags);
extern int my_mkdir(const char *dir, int Flags, myf MyFlags);
extern int my_readlink(char *to, const char *filename, myf MyFlags);
extern int my_realpath(char *to, const char *filename, myf MyFlags);
......@@ -588,6 +590,7 @@ extern void my_free_lock(byte *ptr,myf flags);
void init_alloc_root(MEM_ROOT *mem_root, uint block_size, uint pre_alloc_size);
gptr alloc_root(MEM_ROOT *mem_root,unsigned int Size);
void free_root(MEM_ROOT *root, myf MyFLAGS);
void set_prealloc_root(MEM_ROOT *root, char *ptr);
char *strdup_root(MEM_ROOT *root,const char *str);
char *memdup_root(MEM_ROOT *root,const char *str,uint len);
void load_defaults(const char *conf_file, const char **groups,
......
......@@ -204,6 +204,7 @@ int nisam_extra(N_INFO *info, enum ha_extra_function function)
info->s->changed=1; /* Update on close */
break;
case HA_EXTRA_FORCE_REOPEN:
case HA_EXTRA_PREPARE_FOR_DELETE:
pthread_mutex_lock(&THR_LOCK_isam);
info->s->last_version= 0L; /* Impossible version */
#ifdef __WIN__
......
......@@ -1321,7 +1321,7 @@ int mi_repair(MI_CHECK *param, register MI_INFO *info,
DATA_TMP_EXT, share->base.raid_chunks,
(param->testflag & T_BACKUP_DATA ?
MYF(MY_REDEL_MAKE_BACKUP): MYF(0))) ||
mi_open_datafile(info,share))
mi_open_datafile(info,share,-1))
got_error=1;
}
}
......@@ -2039,7 +2039,7 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info,
DATA_TMP_EXT, share->base.raid_chunks,
(param->testflag & T_BACKUP_DATA ?
MYF(MY_REDEL_MAKE_BACKUP): MYF(0))) ||
mi_open_datafile(info,share))
mi_open_datafile(info,share,-1))
got_error=1;
}
}
......
......@@ -245,12 +245,15 @@ int mi_extra(MI_INFO *info, enum ha_extra_function function)
}
break;
case HA_EXTRA_FORCE_REOPEN:
case HA_EXTRA_PREPARE_FOR_DELETE:
pthread_mutex_lock(&THR_LOCK_myisam);
share->last_version= 0L; /* Impossible version */
#ifdef __WIN__
/* Close the isam and data files as Win32 can't drop an open table */
pthread_mutex_lock(&share->intern_lock);
if (flush_key_blocks(share->kfile,FLUSH_RELEASE))
if (flush_key_blocks(share->kfile,
(function == HA_EXTRA_FORCE_REOPEN ?
FLUSH_RELEASE : FLUSH_IGNORE_CHANGED)))
{
error=my_errno;
share->changed=1;
......
......@@ -366,7 +366,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
lock_error=1; /* Database unlocked */
}
if (mi_open_datafile(&info, share))
if (mi_open_datafile(&info, share, -1))
goto err;
errpos=5;
......@@ -439,7 +439,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
my_errno=EACCES; /* Can't open in write mode */
goto err;
}
if (mi_open_datafile(&info, share))
if (mi_open_datafile(&info, share, old_info->dfile))
goto err;
errpos=5;
}
......@@ -1012,25 +1012,26 @@ char *mi_recinfo_read(char *ptr, MI_COLUMNDEF *recinfo)
** Help functions for recover
*************************************************************************/
int mi_open_datafile(MI_INFO *info, MYISAM_SHARE *share)
int mi_open_datafile(MI_INFO *info, MYISAM_SHARE *share, File file_to_dup)
{
#ifdef USE_RAID
if (share->base.raid_type)
{
if ((info->dfile=my_raid_open(share->data_file_name,
share->mode | O_SHARE,
share->base.raid_type,
share->base.raid_chunks,
share->base.raid_chunksize,
MYF(MY_WME | MY_RAID))) < 0)
return 1;
info->dfile=my_raid_open(share->data_file_name,
share->mode | O_SHARE,
share->base.raid_type,
share->base.raid_chunks,
share->base.raid_chunksize,
MYF(MY_WME | MY_RAID));
}
else
#endif
if ((info->dfile=my_open(share->data_file_name, share->mode | O_SHARE,
MYF(MY_WME))) < 0)
return 1;
return 0;
if (file_to_dup >= 0)
info->dfile=my_dup(file_to_dup,MYF(MY_WME));
else
info->dfile=my_open(share->data_file_name, share->mode | O_SHARE,
MYF(MY_WME));
return info->dfile >= 0 ? 0 : 1;
}
......
......@@ -712,7 +712,7 @@ static int myisamchk(MI_CHECK *param, my_string filename)
error|=change_to_newfile(filename,MI_NAME_DEXT,DATA_TMP_EXT,
raid_chunks,
MYF(0));
if (mi_open_datafile(info,info->s))
if (mi_open_datafile(info,info->s, -1))
error=1;
param->out_flag&= ~O_NEW_DATA; /* We are using new datafile */
param->read_cache.file=info->dfile;
......
......@@ -169,8 +169,8 @@ typedef struct st_mi_isam_share { /* Shared between opens */
ulong last_version; /* Version on start */
ulong options; /* Options used */
uint rec_reflength; /* rec_reflength in use now */
int kfile; /* Shared keyfile */
int data_file; /* Shared data file */
File kfile; /* Shared keyfile */
File data_file; /* Shared data file */
int mode; /* mode of file on open */
uint reopen; /* How many times reopened */
uint w_locks,r_locks; /* Number of read/write locks */
......@@ -642,7 +642,7 @@ my_bool mi_check_status(void* param);
void mi_disable_non_unique_index(MI_INFO *info, ha_rows rows);
my_bool check_table_is_closed(const char *name, const char *where);
int mi_open_datafile(MI_INFO *info, MYISAM_SHARE *share);
int mi_open_datafile(MI_INFO *info, MYISAM_SHARE *share, File file_to_dup);
int mi_open_keyfile(MYISAM_SHARE *share);
int _mi_init_bulk_insert(MI_INFO *info);
......
......@@ -24,7 +24,7 @@ LDADD = libmysys.a ../dbug/libdbug.a \
noinst_HEADERS = mysys_priv.h my_static.h
libmysys_a_SOURCES = my_init.c my_getwd.c mf_getdate.c\
mf_path.c mf_loadpath.c\
my_open.c my_create.c my_seek.c my_read.c \
my_open.c my_create.c my_dup.c my_seek.c my_read.c \
my_pread.c my_write.c \
mf_keycache.c \
mf_iocache.c mf_iocache2.c mf_cache.c mf_tempfile.c \
......
......@@ -148,9 +148,7 @@ static uint calc_hashnr_caseup(const byte *key,uint length)
*
* The magic is in the interesting relationship between the special prime
* 16777619 (2^24 + 403) and 2^32 and 2^8.
*
* This hash produces the fewest collisions of any function that we've seen so
* far, and works well on both numbers and strings.
* This works well on both numbers and strings.
*/
uint calc_hashnr(const byte *key, uint len)
......@@ -514,8 +512,8 @@ my_bool hash_update(HASH *hash,byte *record,byte *old_key,uint old_key_length)
/* Search after record with key */
idx=hash_mask((*hash->calc_hashnr)(old_key,(old_key_length ?
old_key_length :
hash->key_length)),
old_key_length :
hash->key_length)),
blength,records);
new_index=hash_mask(rec_hashnr(hash,record),blength,records);
if (idx == new_index)
......@@ -575,6 +573,17 @@ byte *hash_element(HASH *hash,uint idx)
}
/*
Replace old row with new row. This should only be used when key
isn't changed
*/
void hash_replace(HASH *hash, uint idx, byte *new_row)
{
dynamic_element(&hash->array,idx,HASH_LINK*)->data=new_row;
}
#ifndef DBUG_OFF
my_bool hash_check(HASH *hash)
......
......@@ -40,6 +40,7 @@ void pack_dirname(my_string to, const char *from)
char buff[FN_REFLEN];
DBUG_ENTER("pack_dirname");
LINT_INIT(buff_length);
(void) intern_filename(to,from); /* Change to intern name */
#ifdef FN_DEVCHAR
......@@ -49,7 +50,6 @@ void pack_dirname(my_string to, const char *from)
#endif
start=to;
LINT_INIT(buff_length);
if (!(cwd_err= my_getwd(buff,FN_REFLEN,MYF(0))))
{
buff_length= (uint) strlen(buff);
......
......@@ -55,6 +55,7 @@ gptr alloc_root(MEM_ROOT *mem_root,unsigned int Size)
return((gptr) 0); /* purecov: inspected */
}
next->next=mem_root->used;
next->size= Size;
mem_root->used=next;
return (gptr) (((char*) next)+ALIGN_SIZE(sizeof(USED_MEM)));
#else
......@@ -166,6 +167,31 @@ void free_root(MEM_ROOT *root, myf MyFlags)
DBUG_VOID_RETURN;
}
/*
Find block that contains an object and set the pre_alloc to it
*/
void set_prealloc_root(MEM_ROOT *root, char *ptr)
{
USED_MEM *next;
for (next=root->used; next ; next=next->next)
{
if ((char*) next <= ptr && (char*) next + next->size > ptr)
{
root->pre_alloc=next;
return;
}
}
for (next=root->free ; next ; next=next->next)
{
if ((char*) next <= ptr && (char*) next + next->size > ptr)
{
root->pre_alloc=next;
return;
}
}
}
char *strdup_root(MEM_ROOT *root,const char *str)
{
......
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
MA 02111-1307, USA */
#define USES_TYPES
#include "mysys_priv.h"
#include "mysys_err.h"
#include <my_dir.h>
#include <errno.h>
#if defined(MSDOS) || defined(__WIN__) || defined(__EMX__)
#include <share.h>
#endif
/* Open a file */
File my_dup(File file, myf MyFlags)
{
File fd;
char *filename;
DBUG_ENTER("my_dup");
DBUG_PRINT("my",("file: %d MyFlags: %d", MyFlags));
fd = dup(file);
filename= (((int) file < MY_NFILE) ?
my_file_info[(int) file].name : "Unknown");
DBUG_RETURN(my_register_filename(fd, filename, FILE_BY_DUP,
EE_FILENOTFOUND, MyFlags));
} /* my_open */
......@@ -147,7 +147,8 @@ uint my_fwrite(FILE *stream, const byte *Buffer, uint Count, myf MyFlags)
/* Seek to position in file */
/* ARGSUSED */
my_off_t my_fseek(FILE *stream, my_off_t pos, int whence, myf MyFlags)
my_off_t my_fseek(FILE *stream, my_off_t pos, int whence,
myf MyFlags __attribute__((unused)))
{
DBUG_ENTER("my_fseek");
DBUG_PRINT("my",("stream: %lx pos: %lu whence: %d MyFlags: %d",
......@@ -160,7 +161,7 @@ my_off_t my_fseek(FILE *stream, my_off_t pos, int whence, myf MyFlags)
/* Tell current position of file */
/* ARGSUSED */
my_off_t my_ftell(FILE *stream, myf MyFlags)
my_off_t my_ftell(FILE *stream, myf MyFlags __attribute__((unused)))
{
off_t pos;
DBUG_ENTER("my_ftell");
......
......@@ -577,13 +577,15 @@ myf MyFlags;
** Note that MY_STAT is assumed to be same as struct stat
****************************************************************************/
int my_fstat(int Filedes, MY_STAT *stat_area, myf MyFlags )
int my_fstat(int Filedes, MY_STAT *stat_area,
myf MyFlags __attribute__((unused)))
{
DBUG_ENTER("my_fstat");
DBUG_PRINT("my",("fd: %d MyFlags: %d",Filedes,MyFlags));
DBUG_RETURN(fstat(Filedes, (struct stat *) stat_area));
}
MY_STAT *my_stat(const char *path, MY_STAT *stat_area, myf my_flags)
{
int m_used;
......
......@@ -20,7 +20,7 @@
/* Seek to position in file */
/*ARGSUSED*/
my_off_t my_seek(File fd, my_off_t pos, int whence, myf MyFlags)
my_off_t my_seek(File fd, my_off_t pos, int whence, myf MyFlags __attribute__((unused)))
{
reg1 os_off_t newpos;
DBUG_ENTER("my_seek");
......@@ -40,7 +40,7 @@ my_off_t my_seek(File fd, my_off_t pos, int whence, myf MyFlags)
/* Tell current position of file */
/* ARGSUSED */
my_off_t my_tell(File fd, myf MyFlags)
my_off_t my_tell(File fd, myf MyFlags __attribute__((unused)))
{
os_off_t pos;
DBUG_ENTER("my_tell");
......
......@@ -247,7 +247,7 @@ THR_LOCK_DATA **ha_heap::store_lock(THD *thd,
int ha_heap::delete_table(const char *name)
{
int error=heap_delete_all(name);
int error=heap_delete_table(name);
return error == ENOENT ? 0 : error;
}
......@@ -272,7 +272,6 @@ ha_rows ha_heap::records_in_range(int inx,
return 10; // Good guess
}
/* We can just delete the heap on creation */
int ha_heap::create(const char *name, TABLE *form, HA_CREATE_INFO *create_info)
......
......@@ -1406,7 +1406,10 @@ static void *signal_hand(void *arg __attribute__((unused)))
}
break;
case SIGHUP:
reload_acl_and_cache((THD*) 0,REFRESH_LOG,
reload_acl_and_cache((THD*) 0,
(REFRESH_LOG | REFRESH_TABLES | REFRESH_FAST |
REFRESH_STATUS | REFRESH_GRANT | REFRESH_THREADS |
REFRESH_HOSTS),
(TABLE_LIST*) 0); // Flush logs
mysql_print_status((THD*) 0); // Send debug some info
break;
......@@ -2613,7 +2616,9 @@ static struct option long_options[] = {
{"safemalloc-mem-limit", required_argument, 0, (int)
OPT_SAFEMALLOC_MEM_LIMIT},
{"new", no_argument, 0, 'n'},
#ifdef NOT_YET
{"no-mix-table-types", no_argument, 0, (int)OPT_NO_MIX_TYPE},
#endif
{"old-protocol", no_argument, 0, 'o'},
{"old-rpl-compat", no_argument, 0, (int)OPT_OLD_RPL_COMPAT},
#ifdef ONE_THREAD
......
......@@ -228,3 +228,4 @@
"Wrong usage of %s and %s",
"The used SELECT statements have a different number of columns",
"Can't execute the query because you have a conflicting read lock",
"Mixing of transactional and non-transactional tables is disabled",
......@@ -222,3 +222,4 @@
"Wrong usage of %s and %s",
"The used SELECT statements have a different number of columns",
"Can't execute the query because you have a conflicting read lock",
"Mixing of transactional and non-transactional tables is disabled",
......@@ -223,3 +223,4 @@
"Wrong usage of %s and %s",
"The used SELECT statements have a different number of columns",
"Can't execute the query because you have a conflicting read lock",
"Mixing of transactional and non-transactional tables is disabled",
......@@ -219,4 +219,4 @@
"Wrong usage of %s and %s",
"The used SELECT statements have a different number of columns",
"Can't execute the query because you have a conflicting read lock",
"Mixing transactional and non-transactional tables disabled by option",
\ No newline at end of file
"Mixing of transactional and non-transactional tables is disabled",
......@@ -223,3 +223,4 @@
"Wrong usage of %s and %s",
"The used SELECT statements have a different number of columns",
"Can't execute the query because you have a conflicting read lock",
"Mixing of transactional and non-transactional tables is disabled",
......@@ -219,3 +219,4 @@
"Wrong usage of %s and %s",
"The used SELECT statements have a different number of columns",
"Can't execute the query because you have a conflicting read lock",
"Mixing of transactional and non-transactional tables is disabled",
......@@ -222,3 +222,4 @@
"Wrong usage of %s and %s",
"The used SELECT statements have a different number of columns",
"Can't execute the query because you have a conflicting read lock",
"Mixing of transactional and non-transactional tables is disabled",
......@@ -219,3 +219,4 @@
"Wrong usage of %s and %s",
"The used SELECT statements have a different number of columns",
"Can't execute the query because you have a conflicting read lock",
"Mixing of transactional and non-transactional tables is disabled",
......@@ -221,3 +221,4 @@
"Wrong usage of %s and %s",
"The used SELECT statements have a different number of columns",
"Can't execute the query because you have a conflicting read lock",
"Mixing of transactional and non-transactional tables is disabled",
......@@ -219,3 +219,4 @@
"Wrong usage of %s and %s",
"The used SELECT statements have a different number of columns",
"Can't execute the query because you have a conflicting read lock",
"Mixing of transactional and non-transactional tables is disabled",
......@@ -221,3 +221,4 @@
"Wrong usage of %s and %s",
"The used SELECT statements have a different number of columns",
"Can't execute the query because you have a conflicting read lock",
"Mixing of transactional and non-transactional tables is disabled",
......@@ -219,3 +219,4 @@
"Wrong usage of %s and %s",
"The used SELECT statements have a different number of columns",
"Can't execute the query because you have a conflicting read lock",
"Mixing of transactional and non-transactional tables is disabled",
......@@ -221,3 +221,4 @@
"Wrong usage of %s and %s",
"The used SELECT statements have a different number of columns",
"Can't execute the query because you have a conflicting read lock",
"Mixing of transactional and non-transactional tables is disabled",
......@@ -221,3 +221,4 @@
"Wrong usage of %s and %s",
"The used SELECT statements have a different number of columns",
"Can't execute the query because you have a conflicting read lock",
"Mixing of transactional and non-transactional tables is disabled",
......@@ -223,3 +223,4 @@
"Wrong usage of %s and %s",
"The used SELECT statements have a different number of columns",
"Can't execute the query because you have a conflicting read lock",
"Mixing of transactional and non-transactional tables is disabled",
......@@ -219,3 +219,4 @@
"Wrong usage of %s and %s",
"The used SELECT statements have a different number of columns",
"Can't execute the query because you have a conflicting read lock",
"Mixing of transactional and non-transactional tables is disabled",
......@@ -223,3 +223,4 @@
"Wrong usage of %s and %s",
"The used SELECT statements have a different number of columns",
"Can't execute the query because you have a conflicting read lock",
"Mixing of transactional and non-transactional tables is disabled",
......@@ -222,3 +222,4 @@
"Wrong usage of %s and %s",
"The used SELECT statements have a different number of columns",
"Can't execute the query because you have a conflicting read lock",
"Mixing of transactional and non-transactional tables is disabled",
......@@ -227,3 +227,4 @@
"Wrong usage of %s and %s",
"The used SELECT statements have a different number of columns",
"Can't execute the query because you have a conflicting read lock",
"Mixing of transactional and non-transactional tables is disabled",
......@@ -220,3 +220,4 @@
"Wrong usage of %s and %s",
"The used SELECT statements have a different number of columns",
"Can't execute the query because you have a conflicting read lock",
"Mixing of transactional and non-transactional tables is disabled",
......@@ -219,3 +219,4 @@
"Felaktig använding av %s and %s",
"SELECT kommandona har olika antal kolumner"
"Kan inte utföra kommandot emedan du har ett READ lås",
"Blandning av transaktionella och icke-transaktionella tabeller är stoppat",
......@@ -1368,18 +1368,6 @@ int open_tables(THD *thd,TABLE_LIST *start)
tables->table->reginfo.lock_type=tables->lock_type;
tables->table->grant= tables->grant;
}
if (opt_no_mix_types && start)
{
bool checking; TABLE_LIST *tl;
for (tl=start, checking = tl->table->file->has_transactions(), tl=tl->next; tl ; tl=tl->next)
{
if (((tl->table->file->has_transactions()) ^ checking))
{
send_error(&thd->net,ER_MIXING_NOT_ALLOWED);
DBUG_RETURN(-1);
}
}
}
thd->proc_info=0;
DBUG_RETURN(result);
}
......
......@@ -47,7 +47,7 @@ static void mysql_init_query(THD *thd);
static void remove_escape(char *name);
static void refresh_status(void);
static bool append_file_to_dir(char **filename_ptr, char *table_name);
static int create_total_list(THD *thd, LEX *lex, TABLE_LIST **result);
static bool create_total_list(THD *thd, LEX *lex, TABLE_LIST **result);
const char *any_db="*any*"; // Special symbol for check_access
......@@ -1075,11 +1075,10 @@ mysql_execute_command(void)
/*
Skip if we are in the slave thread, some table rules have been given
and the table list says the query should not be replicated
TODO: UPDATE this for UNION. Updated by Sinisa !!!!!!!!!!!!!!!!!!!!!!
*/
if (lex->select_lex.next && tables && (res = create_total_list(thd,lex,&tables)))
DBUG_VOID_RETURN;
if (table_rules_on && thd->slave_thread && tables && !tables_ok(thd,tables))
if ((lex->select_lex.next && create_total_list(thd,lex,&tables)) ||
(table_rules_on && tables && thd->slave_thread &&
!tables_ok(thd,tables)))
DBUG_VOID_RETURN;
switch (lex->sql_command) {
......@@ -1088,7 +1087,6 @@ mysql_execute_command(void)
select_result *result;
if (select_lex->options & SELECT_DESCRIBE)
lex->exchange=0;
/* Save a call, as it's very uncomon that we use unions */
if (tables)
{
res=check_table_access(thd,
......@@ -2364,6 +2362,7 @@ mysql_init_query(THD *thd)
thd->lex.select = &thd->lex.select_lex;
thd->lex.select_lex.table_list.first=0;
thd->lex.select_lex.table_list.next= (byte**) &thd->lex.select_lex.table_list.first;
thd->lex.select_lex.next=0;
thd->fatal_error=0; // Safety
thd->last_insert_id_used=thd->query_start_used=thd->insert_id_used=0;
thd->sent_row_count=thd->examined_row_count=0;
......@@ -2836,7 +2835,7 @@ TABLE_LIST *add_table_to_list(Table_ident *table, LEX_STRING *alias,
** to the entries in this list.
*/
static int create_total_list(THD *thd, LEX *lex, TABLE_LIST **result)
static bool create_total_list(THD *thd, LEX *lex, TABLE_LIST **result)
{
/* Handle the case when we are not using union */
if (!lex->select_lex.next)
......@@ -2853,8 +2852,8 @@ static int create_total_list(THD *thd, LEX *lex, TABLE_LIST **result)
{
if (sl->order_list.first && sl->next)
{
my_error(ER_WRONG_USAGE,MYF(0),"UNION","ORDER BY");
return -1;
net_printf(&thd->net,ER_WRONG_USAGE,"UNION","ORDER BY");
return 1;
}
if ((aux= (TABLE_LIST*) sl->table_list.first))
{
......@@ -2874,7 +2873,10 @@ static int create_total_list(THD *thd, LEX *lex, TABLE_LIST **result)
aux->lock_type= lex->lock_option;
if (!(cursor = (TABLE_LIST *) thd->memdup((byte*) aux,
sizeof(*aux))))
return -1;
{
send_error(&thd->net,0);
return 1;
}
*new_table_list= cursor;
new_table_list= &cursor->next;
*new_table_list=0; // end result list
......
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