Merge mysql.com:/home/jimw/my/mysql-4.1-14009
into mysql.com:/home/jimw/my/mysql-4.1-clean
This commit is contained in:
commit
7a8bd252d2
27
Makefile.am
27
Makefile.am
@ -97,29 +97,22 @@ tags:
|
||||
support-files/build-tags
|
||||
.PHONY: init-db bin-dist
|
||||
|
||||
# Test installation. Ports are configurable from the environment.
|
||||
|
||||
MYSQL_TEST_MANAGER_PORT = 9305
|
||||
MYSQL_TEST_MASTER_PORT = 9306
|
||||
MYSQL_TEST_SLAVE_PORT = 9308
|
||||
MYSQL_TEST_NDB_PORT = 9350
|
||||
# Target 'test' will run the regression test suite using the built server.
|
||||
#
|
||||
# If you are running in a shared environment, users can avoid clashing
|
||||
# port numbers by setting individual small numbers 1-100 to the
|
||||
# environment variable MTR_BUILD_THREAD. The script "mysql-test-run"
|
||||
# will then calculate the various port numbers it needs from this,
|
||||
# making sure each user use different ports.
|
||||
|
||||
test:
|
||||
cd mysql-test ; \
|
||||
./mysql-test-run \
|
||||
--manager-port=$(MYSQL_TEST_MANAGER_PORT) \
|
||||
--master_port=$(MYSQL_TEST_MASTER_PORT) \
|
||||
--slave_port=$(MYSQL_TEST_SLAVE_PORT) \
|
||||
--ndbcluster_port=$(MYSQL_TEST_NDB_PORT) && \
|
||||
./mysql-test-run --ps-protocol \
|
||||
--manager-port=$(MYSQL_TEST_MANAGER_PORT) \
|
||||
--master_port=$(MYSQL_TEST_MASTER_PORT) \
|
||||
--slave_port=$(MYSQL_TEST_SLAVE_PORT) \
|
||||
--ndbcluster_port=$(MYSQL_TEST_NDB_PORT)
|
||||
./mysql-test-run && \
|
||||
./mysql-test-run --ps-protocol
|
||||
|
||||
test-force:
|
||||
cd mysql-test; \
|
||||
./mysql-test-run --force ;\
|
||||
./mysql-test-run --force ; \
|
||||
./mysql-test-run --ps-protocol --force
|
||||
|
||||
# We are testing a new Perl version of the test script
|
||||
|
@ -167,7 +167,7 @@ static int check_one_rb_key(HP_INFO *info, uint keynr, ulong records,
|
||||
ulong found= 0;
|
||||
byte *key, *recpos;
|
||||
uint key_length;
|
||||
uint not_used;
|
||||
uint not_used[2];
|
||||
|
||||
if ((key= tree_search_edge(&keydef->rb_tree, info->parents,
|
||||
&info->last_pos, offsetof(TREE_ELEMENT, left))))
|
||||
@ -177,7 +177,7 @@ static int check_one_rb_key(HP_INFO *info, uint keynr, ulong records,
|
||||
memcpy(&recpos, key + (*keydef->get_key_length)(keydef,key), sizeof(byte*));
|
||||
key_length= hp_rb_make_key(keydef, info->recbuf, recpos, 0);
|
||||
if (ha_key_cmp(keydef->seg, (uchar*) info->recbuf, (uchar*) key,
|
||||
key_length, SEARCH_FIND | SEARCH_SAME, ¬_used))
|
||||
key_length, SEARCH_FIND | SEARCH_SAME, not_used))
|
||||
{
|
||||
error= 1;
|
||||
DBUG_PRINT("error",("Record in wrong link: key: %d Record: %lx\n",
|
||||
|
@ -170,9 +170,9 @@ int heap_create(const char *name, uint keys, HP_KEYDEF *keydef,
|
||||
|
||||
static int keys_compare(heap_rb_param *param, uchar *key1, uchar *key2)
|
||||
{
|
||||
uint not_used;
|
||||
uint not_used[2];
|
||||
return ha_key_cmp(param->keyseg, key1, key2, param->key_length,
|
||||
param->search_flag, ¬_used);
|
||||
param->search_flag, not_used);
|
||||
}
|
||||
|
||||
static void init_block(HP_BLOCK *block, uint reclength, ulong min_records,
|
||||
|
@ -63,4 +63,6 @@ extern int ha_key_cmp(register HA_KEYSEG *keyseg, register uchar *a,
|
||||
register uchar *b, uint key_length, uint nextflag,
|
||||
uint *diff_pos);
|
||||
|
||||
extern HA_KEYSEG *ha_find_null(HA_KEYSEG *keyseg, uchar *a);
|
||||
|
||||
#endif /* _my_handler_h */
|
||||
|
@ -322,7 +322,9 @@ typedef enum
|
||||
/* Treat NULLs as inequal when collecting statistics (default for 4.1/5.0) */
|
||||
MI_STATS_METHOD_NULLS_NOT_EQUAL,
|
||||
/* Treat NULLs as equal when collecting statistics (like 4.0 did) */
|
||||
MI_STATS_METHOD_NULLS_EQUAL
|
||||
MI_STATS_METHOD_NULLS_EQUAL,
|
||||
/* Ignore NULLs - count only tuples without NULLs in the index components */
|
||||
MI_STATS_METHOD_IGNORE_NULLS
|
||||
} enum_mi_stats_method;
|
||||
|
||||
typedef struct st_mi_check_param
|
||||
@ -349,7 +351,14 @@ typedef struct st_mi_check_param
|
||||
int tmpfile_createflag;
|
||||
myf myf_rw;
|
||||
IO_CACHE read_cache;
|
||||
|
||||
/*
|
||||
The next two are used to collect statistics, see update_key_parts for
|
||||
description.
|
||||
*/
|
||||
ulonglong unique_count[MI_MAX_KEY_SEG+1];
|
||||
ulonglong notnull_count[MI_MAX_KEY_SEG+1];
|
||||
|
||||
ha_checksum key_crc[MI_MAX_POSSIBLE_KEY];
|
||||
ulong rec_per_key_part[MI_MAX_KEY_SEG*MI_MAX_POSSIBLE_KEY];
|
||||
void *thd;
|
||||
@ -409,7 +418,8 @@ void update_auto_increment_key(MI_CHECK *param, MI_INFO *info,
|
||||
my_bool repair);
|
||||
int update_state_info(MI_CHECK *param, MI_INFO *info,uint update);
|
||||
void update_key_parts(MI_KEYDEF *keyinfo, ulong *rec_per_key_part,
|
||||
ulonglong *unique, ulonglong records);
|
||||
ulonglong *unique, ulonglong *notnull,
|
||||
ulonglong records);
|
||||
int filecopy(MI_CHECK *param, File to,File from,my_off_t start,
|
||||
my_off_t length, const char *type);
|
||||
int movepoint(MI_INFO *info,byte *record,my_off_t oldpos,
|
||||
|
@ -1,16 +0,0 @@
|
||||
include ..\include\makefile.i
|
||||
|
||||
btr.lib: btr0cur.obj btr0btr.obj btr0pcur.obj btr0sea.obj
|
||||
lib -out:..\libs\btr.lib btr0cur.obj btr0btr.obj btr0pcur.obj btr0sea.obj
|
||||
|
||||
btr0cur.obj: btr0cur.c
|
||||
$(CCOM) $(CFL) -c btr0cur.c
|
||||
|
||||
btr0btr.obj: btr0btr.c
|
||||
$(CCOM) $(CFL) -c btr0btr.c
|
||||
|
||||
btr0sea.obj: btr0sea.c
|
||||
$(CCOM) $(CFL) -c btr0sea.c
|
||||
|
||||
btr0pcur.obj: btr0pcur.c
|
||||
$(CCOM) $(CFL) -c btr0pcur.c
|
@ -1,20 +0,0 @@
|
||||
include ..\include\makefile.i
|
||||
|
||||
buf.lib: buf0buf.obj buf0lru.obj buf0flu.obj buf0rea.obj
|
||||
lib -out:..\libs\buf.lib buf0buf.obj buf0lru.obj buf0flu.obj buf0rea.obj
|
||||
|
||||
buf0buf.obj: buf0buf.c
|
||||
$(CCOM) $(CFL) -c buf0buf.c
|
||||
|
||||
buf0lru.obj: buf0lru.c
|
||||
$(CCOM) $(CFL) -c buf0lru.c
|
||||
|
||||
buf0flu.obj: buf0flu.c
|
||||
$(CCOM) $(CFL) -c buf0flu.c
|
||||
|
||||
buf0rea.obj: buf0rea.c
|
||||
$(CCOM) $(CFL) -c buf0rea.c
|
||||
|
||||
|
||||
|
||||
|
@ -1,11 +0,0 @@
|
||||
include ..\include\makefile.i
|
||||
|
||||
data.lib: data0type.obj data0data.obj
|
||||
lib -out:..\libs\data.lib data0type.obj data0data.obj
|
||||
|
||||
data0type.obj: data0type.c
|
||||
$(CCOM) $(CFL) -c data0type.c
|
||||
|
||||
data0data.obj: data0data.c
|
||||
$(CCOM) $(CFL) -c data0data.c
|
||||
|
@ -1,21 +0,0 @@
|
||||
include ..\include\makefile.i
|
||||
|
||||
dict.lib: dict0dict.obj dict0boot.obj dict0load.obj dict0mem.obj dict0crea.obj
|
||||
lib -out:..\libs\dict.lib dict0dict.obj dict0boot.obj dict0load.obj dict0mem.obj dict0crea.obj
|
||||
|
||||
dict0dict.obj: dict0dict.c
|
||||
$(CCOM) $(CFL) -c dict0dict.c
|
||||
|
||||
dict0boot.obj: dict0boot.c
|
||||
$(CCOM) $(CFL) -c dict0boot.c
|
||||
|
||||
dict0mem.obj: dict0mem.c
|
||||
$(CCOM) $(CFL) -c dict0mem.c
|
||||
|
||||
dict0crea.obj: dict0crea.c
|
||||
$(CCOM) $(CFL) -c dict0crea.c
|
||||
|
||||
dict0load.obj: dict0load.c
|
||||
$(CCOM) $(CFL) -c dict0load.c
|
||||
|
||||
|
@ -1,9 +0,0 @@
|
||||
include ..\include\makefile.i
|
||||
|
||||
dyn.lib: dyn0dyn.obj makefile
|
||||
lib -out:..\libs\dyn.lib dyn0dyn.obj
|
||||
|
||||
dyn0dyn.obj: dyn0dyn.c
|
||||
$(CCOM) $(CFL) -c dyn0dyn.c
|
||||
|
||||
|
@ -1,10 +0,0 @@
|
||||
include ..\include\makefile.i
|
||||
|
||||
eval.lib: eval0eval.obj eval0proc.obj
|
||||
lib -out:..\libs\eval.lib eval0eval.obj eval0proc.obj
|
||||
|
||||
eval0eval.obj: eval0eval.c
|
||||
$(CCOM) $(CFL) -c eval0eval.c
|
||||
|
||||
eval0proc.obj: eval0proc.c
|
||||
$(CCOM) $(CFL) -c eval0proc.c
|
@ -1,10 +0,0 @@
|
||||
include ..\include\makefile.i
|
||||
|
||||
fil.lib: fil0fil.obj
|
||||
lib -out:..\libs\fil.lib fil0fil.obj
|
||||
|
||||
fil0fil.obj: fil0fil.c
|
||||
$(CCOM) $(CFL) -c fil0fil.c
|
||||
|
||||
|
||||
|
@ -1,9 +0,0 @@
|
||||
include ..\include\makefile.i
|
||||
|
||||
fsp.lib: fsp0fsp.obj
|
||||
lib -out:..\libs\fsp.lib fsp0fsp.obj
|
||||
|
||||
fsp0fsp.obj: fsp0fsp.c
|
||||
$(CCOM) $(CFL) -c fsp0fsp.c
|
||||
|
||||
|
@ -1,12 +0,0 @@
|
||||
include ..\include\makefile.i
|
||||
|
||||
fut.lib: fut0lst.obj fut0fut.obj
|
||||
lib -out:..\libs\fut.lib fut0lst.obj fut0fut.obj
|
||||
|
||||
fut0lst.obj: fut0lst.c
|
||||
$(CCOM) $(CFL) -c fut0lst.c
|
||||
|
||||
fut0fut.obj: fut0fut.c
|
||||
$(CCOM) $(CFL) -c fut0fut.c
|
||||
|
||||
|
@ -1,10 +0,0 @@
|
||||
include ..\include\makefile.i
|
||||
|
||||
ha.lib: ha0ha.obj hash0hash.obj
|
||||
lib -out:..\libs\ha.lib ha0ha.obj hash0hash.obj
|
||||
|
||||
ha0ha.obj: ha0ha.c
|
||||
$(CCOM) $(CFL) -c ha0ha.c
|
||||
|
||||
hash0hash.obj: hash0hash.c
|
||||
$(CCOM) $(CFL) -c hash0hash.c
|
@ -1,7 +0,0 @@
|
||||
include ..\include\makefile.i
|
||||
|
||||
ibuf.lib: ibuf0ibuf.obj
|
||||
lib -out:..\libs\ibuf.lib ibuf0ibuf.obj
|
||||
|
||||
ibuf0ibuf.obj: ibuf0ibuf.c
|
||||
$(CCOM) $(CFL) -c ibuf0ibuf.c
|
@ -28,7 +28,7 @@ noinst_HEADERS = btr0btr.h btr0btr.ic btr0cur.h btr0cur.ic \
|
||||
ha0ha.h ha0ha.ic hash0hash.h hash0hash.ic \
|
||||
ibuf0ibuf.h ibuf0ibuf.ic ibuf0types.h lock0lock.h \
|
||||
lock0lock.ic lock0types.h log0log.h log0log.ic log0recv.h \
|
||||
log0recv.ic mach0data.h mach0data.ic makefilewin.i \
|
||||
log0recv.ic mach0data.h mach0data.ic \
|
||||
mem0dbg.h mem0dbg.ic mem0mem.h mem0mem.ic mem0pool.h \
|
||||
mem0pool.ic mtr0log.h mtr0log.ic mtr0mtr.h mtr0mtr.ic \
|
||||
mtr0types.h os0file.h os0proc.h os0proc.ic \
|
||||
|
@ -1,34 +0,0 @@
|
||||
# File included in all makefiles of the database
|
||||
# (c) Innobase Oy 1995 - 2000
|
||||
|
||||
CCOM=cl
|
||||
|
||||
# Flags for the debug version
|
||||
#CFL= -MTd -Za -Zi -W4 -WX -F8192 -D "WIN32"
|
||||
#CFLN = -MTd -Zi -W4 -F8192 -D "WIN32"
|
||||
#CFLW = -MTd -Zi -W3 -WX -F8192 -D "WIN32"
|
||||
#LFL =
|
||||
|
||||
# Flags for the fast version
|
||||
#CFL= -MT -Zi -Og -O2 -W3 -WX -D "WIN32"
|
||||
#CFLN = -MT -Zi -Og -O2 -W3 -D "WIN32"
|
||||
#CFLW = -MT -Zi -Og -O2 -W3 -WX -D "WIN32"
|
||||
#LFL =
|
||||
|
||||
# Flags for the fast debug version
|
||||
CFL= -MTd -Zi -W3 -WX -F8192 -D "WIN32"
|
||||
CFLN = -MTd -Zi -W3 -F8192 -D "WIN32"
|
||||
CFLW = -MTd -Zi -W3 -WX -F8192 -D "WIN32"
|
||||
LFL = /link/NODEFAULTLIB:LIBCMT
|
||||
|
||||
# Flags for the profiler version
|
||||
#CFL= -MT -Zi -Og -O2 -W3 -WX -D "WIN32"
|
||||
#CFLN = -MT -Zi -Og -O2 -WX -D "WIN32"
|
||||
#CFLW = -MT -Zi -Og -O2 -W3 -WX -D "WIN32"
|
||||
#LFL= -link -PROFILE
|
||||
|
||||
# Flags for the fast version without debug info (= the production version)
|
||||
#CFL= -MT -Og -O2 -G6 -W3 -WX -D "WIN32"
|
||||
#CFLN = -MT -Og -O2 -G6 -W3 -D "WIN32"
|
||||
#CFLW = -MT -Og -O2 -G6 -W3 -WX -D "WIN32"
|
||||
#LFL =
|
@ -1,7 +0,0 @@
|
||||
include ..\include\makefile.i
|
||||
|
||||
lock.lib: lock0lock.obj
|
||||
lib -out:..\libs\lock.lib lock0lock.obj
|
||||
|
||||
lock0lock.obj: lock0lock.c
|
||||
$(CCOM) $(CFL) -c lock0lock.c
|
@ -1,10 +0,0 @@
|
||||
include ..\include\makefile.i
|
||||
|
||||
log.lib: log0log.obj log0recv.obj
|
||||
lib -out:..\libs\log.lib log0log.obj log0recv.obj
|
||||
|
||||
log0log.obj: log0log.c
|
||||
$(CCOM) $(CFL) -c log0log.c
|
||||
|
||||
log0recv.obj: log0recv.c
|
||||
$(CCOM) $(CFL) -c log0recv.c
|
@ -1,9 +0,0 @@
|
||||
include ..\include\makefile.i
|
||||
|
||||
mach.lib: mach0data.obj
|
||||
lib -out:..\libs\mach.lib mach0data.obj
|
||||
|
||||
mach0data.obj: mach0data.c
|
||||
$(CCOM) $(CFLN) -c mach0data.c
|
||||
|
||||
|
@ -1,164 +0,0 @@
|
||||
doall: del_libs pb_all os.lib ut.lib mach.lib sync.lib mem.lib dyn.lib ha.lib com.lib thr.lib srv.lib fil.lib buf.lib log.lib mtr.lib log.lib fut.lib fsp.lib dict.lib data.lib rem.lib page.lib btr.lib ibuf.lib usr.lib que.lib trx.lib lock.lib read.lib row.lib pars.lib eval.lib ib_odbc.lib
|
||||
|
||||
del_libs:
|
||||
cd libs
|
||||
del *.lib
|
||||
cd ..
|
||||
|
||||
pb_all:
|
||||
pb_all
|
||||
|
||||
os.lib:
|
||||
cd os
|
||||
remake
|
||||
cd ..
|
||||
|
||||
ut.lib:
|
||||
cd ut
|
||||
remake
|
||||
cd ..
|
||||
|
||||
mach.lib:
|
||||
cd mach
|
||||
remake
|
||||
cd ..
|
||||
|
||||
sync.lib:
|
||||
cd sync
|
||||
remake
|
||||
cd ..
|
||||
|
||||
mem.lib:
|
||||
cd mem
|
||||
remake
|
||||
cd ..
|
||||
|
||||
dyn.lib:
|
||||
cd dyn
|
||||
remake
|
||||
cd ..
|
||||
|
||||
ha.lib:
|
||||
cd ha
|
||||
remake
|
||||
cd ..
|
||||
|
||||
com.lib:
|
||||
cd com
|
||||
remake
|
||||
cd ..
|
||||
|
||||
thr.lib:
|
||||
cd thr
|
||||
remake
|
||||
cd ..
|
||||
|
||||
srv.lib:
|
||||
cd srv
|
||||
remake
|
||||
cd ..
|
||||
|
||||
fil.lib:
|
||||
cd fil
|
||||
remake
|
||||
cd ..
|
||||
|
||||
buf.lib:
|
||||
cd buf
|
||||
remake
|
||||
cd ..
|
||||
|
||||
log.lib:
|
||||
cd log
|
||||
remake
|
||||
cd ..
|
||||
|
||||
mtr.lib:
|
||||
cd mtr
|
||||
remake
|
||||
cd ..
|
||||
|
||||
fut.lib:
|
||||
cd fut
|
||||
remake
|
||||
cd ..
|
||||
|
||||
fsp.lib:
|
||||
cd fsp
|
||||
remake
|
||||
cd ..
|
||||
|
||||
dict.lib:
|
||||
cd dict
|
||||
remake
|
||||
cd ..
|
||||
|
||||
data.lib:
|
||||
cd data
|
||||
remake
|
||||
cd ..
|
||||
|
||||
rem.lib:
|
||||
cd rem
|
||||
remake
|
||||
cd ..
|
||||
|
||||
page.lib:
|
||||
cd page
|
||||
remake
|
||||
cd ..
|
||||
|
||||
btr.lib:
|
||||
cd btr
|
||||
remake
|
||||
cd ..
|
||||
|
||||
ibuf.lib:
|
||||
cd ibuf
|
||||
remake
|
||||
cd ..
|
||||
|
||||
usr.lib:
|
||||
cd usr
|
||||
remake
|
||||
cd ..
|
||||
|
||||
que.lib:
|
||||
cd que
|
||||
remake
|
||||
cd ..
|
||||
|
||||
trx.lib:
|
||||
cd trx
|
||||
remake
|
||||
cd ..
|
||||
|
||||
lock.lib:
|
||||
cd lock
|
||||
remake
|
||||
cd ..
|
||||
|
||||
read.lib:
|
||||
cd read
|
||||
remake
|
||||
cd ..
|
||||
|
||||
row.lib:
|
||||
cd row
|
||||
remake
|
||||
cd ..
|
||||
|
||||
pars.lib:
|
||||
cd pars
|
||||
remake
|
||||
cd ..
|
||||
|
||||
eval.lib:
|
||||
cd eval
|
||||
remake
|
||||
cd ..
|
||||
|
||||
ib_odbc.lib:
|
||||
cd odbc
|
||||
remake
|
||||
cd ..
|
@ -1,10 +0,0 @@
|
||||
include ..\include\makefile.i
|
||||
|
||||
mem.lib: mem0mem.obj mem0pool.obj makefile
|
||||
lib -out:..\libs\mem.lib mem0mem.obj mem0pool.obj
|
||||
|
||||
mem0mem.obj: mem0mem.c mem0dbg.c
|
||||
$(CCOM) $(CFL) -c mem0mem.c
|
||||
|
||||
mem0pool.obj: mem0pool.c
|
||||
$(CCOM) $(CFL) -c mem0pool.c
|
@ -1,14 +0,0 @@
|
||||
include ..\include\makefile.i
|
||||
|
||||
mtr.lib: mtr0mtr.obj mtr0log.obj
|
||||
lib -out:..\libs\mtr.lib mtr0mtr.obj mtr0log.obj
|
||||
|
||||
mtr0mtr.obj: mtr0mtr.c
|
||||
$(CCOM) $(CFL) -c mtr0mtr.c
|
||||
|
||||
mtr0log.obj: mtr0log.c
|
||||
$(CCOM) $(CFL) -c mtr0log.c
|
||||
|
||||
|
||||
|
||||
|
@ -1,63 +0,0 @@
|
||||
# Example mysql config file.
|
||||
# Copy this file to c:\my.cnf to set global options
|
||||
#
|
||||
# One can use all long options that the program supports.
|
||||
# Run the program with --help to get a list of available options
|
||||
|
||||
# This will be passed to all mysql clients
|
||||
[client]
|
||||
#password=my_password
|
||||
port=3306
|
||||
#socket=MySQL
|
||||
|
||||
# Here is entries for some specific programs
|
||||
# The following values assume you have at least 32M ram
|
||||
|
||||
# The MySQL server
|
||||
[mysqld]
|
||||
port=3306
|
||||
#socket=MySQL
|
||||
skip-locking
|
||||
default-character-set=latin1
|
||||
set-variable = key_buffer=2M
|
||||
set-variable = max_allowed_packet=1M
|
||||
set-variable = thread_stack=128K
|
||||
set-variable = flush_time=1800
|
||||
|
||||
innobase_data_home_dir = e:\ibdata\
|
||||
innobase_data_file_path = ibdata1:25M;ibdata2:37M;ibdata3:100M;ibdata4:300M
|
||||
set-variable = innobase_mirrored_log_groups=1
|
||||
innobase_log_group_home_dir = e:\iblogs\
|
||||
set-variable = innobase_log_files_in_group=3
|
||||
set-variable = innobase_log_file_size=5M
|
||||
set-variable = innobase_log_buffer_size=8M
|
||||
innobase_flush_log_at_trx_commit=1
|
||||
innobase_log_arch_dir = e:\iblogs\
|
||||
innobase_log_archive=0
|
||||
set-variable = innobase_buffer_pool_size=16M
|
||||
set-variable = innobase_additional_mem_pool_size=2M
|
||||
set-variable = innobase_file_io_threads=4
|
||||
set-variable = innobase_lock_wait_timeout=50
|
||||
|
||||
|
||||
# Uncomment the following row if you move the MySQL distribution to another
|
||||
# location
|
||||
#basedir = d:/mysql/
|
||||
|
||||
[mysqldump]
|
||||
quick
|
||||
set-variable = max_allowed_packet=16M
|
||||
|
||||
[mysql]
|
||||
no-auto-rehash
|
||||
|
||||
[isamchk]
|
||||
set-variable= key=16M
|
||||
|
||||
[client_fltk]
|
||||
help_file= c:\mysql\sql_client\MySQL.help
|
||||
client_file= c:\mysql\MySQL.options
|
||||
history_length=20
|
||||
database = test
|
||||
queries_root= c:\mysql\queries
|
||||
last_database_file= c:\mysql\lastdb
|
@ -1,17 +0,0 @@
|
||||
include ..\include\makefile.i
|
||||
|
||||
os.lib: os0sync.obj os0thread.obj os0proc.obj os0file.obj
|
||||
lib -out:..\libs\os.lib os0sync.obj os0thread.obj os0proc.obj os0file.obj
|
||||
|
||||
os0sync.obj: os0sync.c
|
||||
$(CCOM) $(CFLW) -c os0sync.c
|
||||
|
||||
os0thread.obj: os0thread.c
|
||||
$(CCOM) $(CFLW) -c os0thread.c
|
||||
|
||||
os0proc.obj: os0proc.c
|
||||
$(CCOM) $(CFLW) -c os0proc.c
|
||||
|
||||
os0file.obj: os0file.c
|
||||
$(CCOM) $(CFLW) -c os0file.c
|
||||
|
@ -1,12 +0,0 @@
|
||||
include ..\include\makefile.i
|
||||
|
||||
page.lib: page0page.obj page0cur.obj
|
||||
lib -out:..\libs\page.lib page0page.obj page0cur.obj
|
||||
|
||||
page0page.obj: page0page.c
|
||||
$(CCOM) $(CFL) -c page0page.c
|
||||
|
||||
page0cur.obj: page0cur.c
|
||||
$(CCOM) $(CFL) -c page0cur.c
|
||||
|
||||
|
@ -1,26 +0,0 @@
|
||||
include ..\include\makefile.i
|
||||
|
||||
pars.lib: pars0grm.obj lexyy.obj pars0pars.obj pars0opt.obj pars0sym.obj rename_and_copy
|
||||
lib -out:..\libs\pars.lib pars0grm.obj lexyy.obj pars0pars.obj pars0opt.obj pars0sym.obj
|
||||
|
||||
pars0grm.obj: pars0grm.y
|
||||
bs pars0grm.y
|
||||
$(CCOM) $(CFLW) -c pars0grm.c
|
||||
|
||||
rename_and_copy:
|
||||
ren pars0grm.h pars0grm.h
|
||||
copy pars0grm.h ..\include
|
||||
|
||||
lexyy.obj: pars0lex.l
|
||||
fl pars0lex.l
|
||||
$(CCOM) $(CFLN) -c lexyy.c
|
||||
|
||||
pars0pars.obj: pars0pars.c
|
||||
$(CCOM) $(CFL) -c pars0pars.c
|
||||
|
||||
pars0opt.obj: pars0opt.c
|
||||
$(CCOM) $(CFL) -c pars0opt.c
|
||||
|
||||
pars0sym.obj: pars0sym.c
|
||||
$(CCOM) $(CFL) -c pars0sym.c
|
||||
|
@ -1,7 +0,0 @@
|
||||
include ..\include\makefile.i
|
||||
|
||||
que.lib: que0que.obj
|
||||
lib -out:..\libs\que.lib que0que.obj
|
||||
|
||||
que0que.obj: que0que.c
|
||||
$(CCOM) $(CFL) -c que0que.c
|
@ -1,7 +0,0 @@
|
||||
include ..\include\makefile.i
|
||||
|
||||
read.lib: read0read.obj
|
||||
lib -out:..\libs\read.lib read0read.obj
|
||||
|
||||
read0read.obj: read0read.c
|
||||
$(CCOM) $(CFL) -c read0read.c
|
@ -1,12 +0,0 @@
|
||||
include ..\include\makefile.i
|
||||
|
||||
rem.lib: rem0rec.obj rem0cmp.obj
|
||||
lib -out:..\libs\rem.lib rem0rec.obj rem0cmp.obj
|
||||
|
||||
rem0rec.obj: rem0rec.c
|
||||
$(CCOM) $(CFL) -c rem0rec.c
|
||||
|
||||
rem0cmp.obj: rem0cmp.c
|
||||
$(CCOM) $(CFL) -c rem0cmp.c
|
||||
|
||||
|
@ -1,34 +0,0 @@
|
||||
include ..\include\makefile.i
|
||||
|
||||
row.lib: row0mysql.obj row0upd.obj row0sel.obj row0umod.obj row0uins.obj row0ins.obj row0upd.obj row0undo.obj row0purge.obj row0vers.obj row0row.obj
|
||||
lib -out:..\libs\row.lib row0mysql.obj row0sel.obj row0umod.obj row0uins.obj row0ins.obj row0upd.obj row0undo.obj row0purge.obj row0vers.obj row0row.obj
|
||||
|
||||
row0mysql.obj: row0mysql.c
|
||||
$(CCOM) $(CFL) -c row0mysql.c
|
||||
|
||||
row0ins.obj: row0ins.c
|
||||
$(CCOM) $(CFL) -c row0ins.c
|
||||
|
||||
row0sel.obj: row0sel.c
|
||||
$(CCOM) $(CFL) -c row0sel.c
|
||||
|
||||
row0upd.obj: row0upd.c
|
||||
$(CCOM) $(CFL) -c row0upd.c
|
||||
|
||||
row0undo.obj: row0undo.c
|
||||
$(CCOM) $(CFL) -c row0undo.c
|
||||
|
||||
row0purge.obj: row0purge.c
|
||||
$(CCOM) $(CFL) -c row0purge.c
|
||||
|
||||
row0row.obj: row0row.c
|
||||
$(CCOM) $(CFL) -c row0row.c
|
||||
|
||||
row0vers.obj: row0vers.c
|
||||
$(CCOM) $(CFL) -c row0vers.c
|
||||
|
||||
row0umod.obj: row0umod.c
|
||||
$(CCOM) $(CFL) -c row0umod.c
|
||||
|
||||
row0uins.obj: row0uins.c
|
||||
$(CCOM) $(CFL) -c row0uins.c
|
@ -1,15 +0,0 @@
|
||||
include ..\include\makefile.i
|
||||
|
||||
srv.lib: srv0srv.obj srv0que.obj srv0start.obj
|
||||
lib -out:..\libs\srv.lib srv0srv.obj srv0que.obj srv0start.obj
|
||||
|
||||
srv0srv.obj: srv0srv.c
|
||||
$(CCOM) $(CFL) -c srv0srv.c
|
||||
|
||||
srv0que.obj: srv0que.c
|
||||
$(CCOM) $(CFL) -c srv0que.c
|
||||
|
||||
srv0start.obj: srv0start.c
|
||||
$(CCOM) $(CFL) -c srv0start.c
|
||||
|
||||
|
@ -1,14 +0,0 @@
|
||||
include ..\include\makefile.i
|
||||
|
||||
sync.lib: sync0sync.obj sync0rw.obj sync0arr.obj
|
||||
lib -out:..\libs\sync.lib sync0sync.obj sync0rw.obj sync0arr.obj
|
||||
|
||||
sync0sync.obj: sync0sync.c
|
||||
$(CCOM) $(CFLN) -c sync0sync.c
|
||||
|
||||
sync0rw.obj: sync0rw.c
|
||||
$(CCOM) $(CFL) -c sync0rw.c
|
||||
|
||||
sync0arr.obj: sync0arr.c
|
||||
$(CCOM) $(CFL) -c sync0arr.c
|
||||
|
@ -1,9 +0,0 @@
|
||||
include ..\include\makefile.i
|
||||
|
||||
thr.lib: thr0loc.obj
|
||||
lib -out:..\libs\thr.lib thr0loc.obj
|
||||
|
||||
thr0loc.obj: thr0loc.c
|
||||
$(CCOM) $(CFL) -c thr0loc.c
|
||||
|
||||
|
@ -1,26 +0,0 @@
|
||||
include ..\include\makefile.i
|
||||
|
||||
trx.lib: trx0sys.obj trx0trx.obj trx0rseg.obj trx0undo.obj trx0rec.obj trx0roll.obj trx0purge.obj
|
||||
lib -out:..\libs\trx.lib trx0sys.obj trx0trx.obj trx0rseg.obj trx0undo.obj trx0rec.obj trx0roll.obj trx0purge.obj
|
||||
|
||||
trx0trx.obj: trx0trx.c
|
||||
$(CCOM) $(CFL) -c -I.. trx0trx.c
|
||||
|
||||
trx0sys.obj: trx0sys.c
|
||||
$(CCOM) $(CFL) -c -I.. trx0sys.c
|
||||
|
||||
trx0rseg.obj: trx0rseg.c
|
||||
$(CCOM) $(CFL) -c -I.. trx0rseg.c
|
||||
|
||||
trx0undo.obj: trx0undo.c
|
||||
$(CCOM) $(CFL) -c -I.. trx0undo.c
|
||||
|
||||
trx0rec.obj: trx0rec.c
|
||||
$(CCOM) $(CFL) -c -I.. trx0rec.c
|
||||
|
||||
trx0roll.obj: trx0roll.c
|
||||
$(CCOM) $(CFL) -c -I.. trx0roll.c
|
||||
|
||||
trx0purge.obj: trx0purge.c
|
||||
$(CCOM) $(CFL) -c -I.. trx0purge.c
|
||||
|
@ -1,7 +0,0 @@
|
||||
include ..\include\makefile.i
|
||||
|
||||
usr.lib: usr0sess.obj
|
||||
lib -out:..\libs\usr.lib usr0sess.obj
|
||||
|
||||
usr0sess.obj: usr0sess.c
|
||||
$(CCOM) $(CFL) -c usr0sess.c
|
@ -1,21 +0,0 @@
|
||||
include ..\include\makefile.i
|
||||
|
||||
ut.lib: ut0ut.obj ut0mem.obj ut0byte.obj ut0dbg.obj ut0rnd.obj
|
||||
lib -out:..\libs\ut.lib ut0ut.obj ut0mem.obj ut0byte.obj ut0dbg.obj ut0rnd.obj
|
||||
|
||||
ut0ut.obj: ut0ut.c
|
||||
$(CCOM) $(CFL) -c ut0ut.c
|
||||
|
||||
ut0mem.obj: ut0mem.c
|
||||
$(CCOM) $(CFL) -c ut0mem.c
|
||||
|
||||
ut0byte.obj: ut0byte.c
|
||||
$(CCOM) $(CFL) -c ut0byte.c
|
||||
|
||||
ut0dbg.obj: ut0dbg.c
|
||||
$(CCOM) $(CFL) -c ut0dbg.c
|
||||
|
||||
ut0rnd.obj: ut0rnd.c
|
||||
$(CCOM) $(CFL) -c ut0rnd.c
|
||||
|
||||
|
@ -391,7 +391,10 @@ int chk_key(MI_CHECK *param, register MI_INFO *info)
|
||||
found_keys++;
|
||||
|
||||
param->record_checksum=init_checksum;
|
||||
|
||||
bzero((char*) ¶m->unique_count,sizeof(param->unique_count));
|
||||
bzero((char*) ¶m->notnull_count,sizeof(param->notnull_count));
|
||||
|
||||
if ((!(param->testflag & T_SILENT)))
|
||||
printf ("- check data record references index: %d\n",key+1);
|
||||
if (keyinfo->flag & HA_FULLTEXT)
|
||||
@ -496,7 +499,9 @@ int chk_key(MI_CHECK *param, register MI_INFO *info)
|
||||
|
||||
if (param->testflag & T_STATISTICS)
|
||||
update_key_parts(keyinfo, rec_per_key_part, param->unique_count,
|
||||
(ulonglong) info->state->records);
|
||||
param->stats_method == MI_STATS_METHOD_IGNORE_NULLS?
|
||||
param->notnull_count: NULL,
|
||||
(ulonglong)info->state->records);
|
||||
}
|
||||
if (param->testflag & T_INFO)
|
||||
{
|
||||
@ -552,6 +557,96 @@ err:
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
"Ignore NULLs" statistics collection method: process first index tuple.
|
||||
|
||||
SYNOPSIS
|
||||
mi_collect_stats_nonulls_first()
|
||||
keyseg IN Array of key part descriptions
|
||||
notnull INOUT Array, notnull[i] = (number of {keypart1...keypart_i}
|
||||
tuples that don't contain NULLs)
|
||||
key IN Key values tuple
|
||||
|
||||
DESCRIPTION
|
||||
Process the first index tuple - find out which prefix tuples don't
|
||||
contain NULLs, and update the array of notnull counters accordingly.
|
||||
*/
|
||||
|
||||
static
|
||||
void mi_collect_stats_nonulls_first(HA_KEYSEG *keyseg, ulonglong *notnull,
|
||||
uchar *key)
|
||||
{
|
||||
uint first_null, kp;
|
||||
first_null= ha_find_null(keyseg, key) - keyseg;
|
||||
/*
|
||||
All prefix tuples that don't include keypart_{first_null} are not-null
|
||||
tuples (and all others aren't), increment counters for them.
|
||||
*/
|
||||
for (kp= 0; kp < first_null; kp++)
|
||||
notnull[kp]++;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
"Ignore NULLs" statistics collection method: process next index tuple.
|
||||
|
||||
SYNOPSIS
|
||||
mi_collect_stats_nonulls_next()
|
||||
keyseg IN Array of key part descriptions
|
||||
notnull INOUT Array, notnull[i] = (number of {keypart1...keypart_i}
|
||||
tuples that don't contain NULLs)
|
||||
prev_key IN Previous key values tuple
|
||||
last_key IN Next key values tuple
|
||||
|
||||
DESCRIPTION
|
||||
Process the next index tuple:
|
||||
1. Find out which prefix tuples of last_key don't contain NULLs, and
|
||||
update the array of notnull counters accordingly.
|
||||
2. Find the first keypart number where the prev_key and last_key tuples
|
||||
are different(A), or last_key has NULL value(B), and return it, so the
|
||||
caller can count number of unique tuples for each key prefix. We don't
|
||||
need (B) to be counted, and that is compensated back in
|
||||
update_key_parts().
|
||||
|
||||
RETURN
|
||||
1 + number of first keypart where values differ or last_key tuple has NULL
|
||||
*/
|
||||
|
||||
static
|
||||
int mi_collect_stats_nonulls_next(HA_KEYSEG *keyseg, ulonglong *notnull,
|
||||
uchar *prev_key, uchar *last_key)
|
||||
{
|
||||
uint diffs[2];
|
||||
uint first_null_seg, kp;
|
||||
HA_KEYSEG *seg;
|
||||
|
||||
/*
|
||||
Find the first keypart where values are different or either of them is
|
||||
NULL. We get results in diffs array:
|
||||
diffs[0]= 1 + number of first different keypart
|
||||
diffs[1]=offset: (last_key + diffs[1]) points to first value in
|
||||
last_key that is NULL or different from corresponding
|
||||
value in prev_key.
|
||||
*/
|
||||
ha_key_cmp(keyseg, prev_key, last_key, USE_WHOLE_KEY,
|
||||
SEARCH_FIND | SEARCH_NULL_ARE_NOT_EQUAL, diffs);
|
||||
seg= keyseg + diffs[0] - 1;
|
||||
|
||||
/* Find first NULL in last_key */
|
||||
first_null_seg= ha_find_null(seg, last_key + diffs[1]) - keyseg;
|
||||
for (kp= 0; kp < first_null_seg; kp++)
|
||||
notnull[kp]++;
|
||||
|
||||
/*
|
||||
Return 1+ number of first key part where values differ. Don't care if
|
||||
these were NULLs and not .... We compensate for that in
|
||||
update_key_parts.
|
||||
*/
|
||||
return diffs[0];
|
||||
}
|
||||
|
||||
|
||||
/* Check if index is ok */
|
||||
|
||||
static int chk_index(MI_CHECK *param, MI_INFO *info, MI_KEYDEF *keyinfo,
|
||||
@ -563,7 +658,7 @@ static int chk_index(MI_CHECK *param, MI_INFO *info, MI_KEYDEF *keyinfo,
|
||||
uchar key[MI_MAX_POSSIBLE_KEY_BUFF],*temp_buff,*keypos,*old_keypos,*endpos;
|
||||
my_off_t next_page,record;
|
||||
char llbuff[22];
|
||||
uint diff_pos;
|
||||
uint diff_pos[2];
|
||||
DBUG_ENTER("chk_index");
|
||||
DBUG_DUMP("buff",(byte*) buff,mi_getint(buff));
|
||||
|
||||
@ -621,7 +716,7 @@ static int chk_index(MI_CHECK *param, MI_INFO *info, MI_KEYDEF *keyinfo,
|
||||
}
|
||||
if ((*keys)++ &&
|
||||
(flag=ha_key_cmp(keyinfo->seg,info->lastkey,key,key_length,
|
||||
comp_flag, &diff_pos)) >=0)
|
||||
comp_flag, diff_pos)) >=0)
|
||||
{
|
||||
DBUG_DUMP("old",(byte*) info->lastkey, info->lastkey_length);
|
||||
DBUG_DUMP("new",(byte*) key, key_length);
|
||||
@ -640,8 +735,20 @@ static int chk_index(MI_CHECK *param, MI_INFO *info, MI_KEYDEF *keyinfo,
|
||||
if (param->stats_method == MI_STATS_METHOD_NULLS_NOT_EQUAL)
|
||||
ha_key_cmp(keyinfo->seg,info->lastkey,key,USE_WHOLE_KEY,
|
||||
SEARCH_FIND | SEARCH_NULL_ARE_NOT_EQUAL,
|
||||
&diff_pos);
|
||||
param->unique_count[diff_pos-1]++;
|
||||
diff_pos);
|
||||
else if (param->stats_method == MI_STATS_METHOD_IGNORE_NULLS)
|
||||
{
|
||||
diff_pos[0]= mi_collect_stats_nonulls_next(keyinfo->seg,
|
||||
param->notnull_count,
|
||||
info->lastkey, key);
|
||||
}
|
||||
param->unique_count[diff_pos[0]-1]++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (param->stats_method == MI_STATS_METHOD_IGNORE_NULLS)
|
||||
mi_collect_stats_nonulls_first(keyinfo->seg, param->notnull_count,
|
||||
key);
|
||||
}
|
||||
}
|
||||
(*key_checksum)+= mi_byte_checksum((byte*) key,
|
||||
@ -1731,9 +1838,10 @@ static int sort_one_index(MI_CHECK *param, MI_INFO *info, MI_KEYDEF *keyinfo,
|
||||
_mi_kpointer(info,keypos-nod_flag,param->new_file_pos); /* Save new pos */
|
||||
if (sort_one_index(param,info,keyinfo,next_page,new_file))
|
||||
{
|
||||
DBUG_PRINT("error",("From page: %ld, keyoffset: %d used_length: %d",
|
||||
(ulong) pagepos, (int) (keypos - buff),
|
||||
(int) used_length));
|
||||
DBUG_PRINT("error",
|
||||
("From page: %ld, keyoffset: 0x%lx used_length: %d",
|
||||
(ulong) pagepos, (ulong) (keypos - buff),
|
||||
(int) used_length));
|
||||
DBUG_DUMP("buff",(byte*) buff,used_length);
|
||||
goto err;
|
||||
}
|
||||
@ -2088,7 +2196,8 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info,
|
||||
|
||||
if (param->testflag & T_STATISTICS)
|
||||
update_key_parts(sort_param.keyinfo, rec_per_key_part, sort_param.unique,
|
||||
(ulonglong) info->state->records);
|
||||
param->stats_method == MI_STATS_METHOD_IGNORE_NULLS?
|
||||
sort_param.notnull: NULL,(ulonglong) info->state->records);
|
||||
share->state.key_map|=(ulonglong) 1 << sort_param.key;
|
||||
|
||||
if (sort_param.fix_datafile)
|
||||
@ -3232,15 +3341,15 @@ int sort_write_record(MI_SORT_PARAM *sort_param)
|
||||
static int sort_key_cmp(MI_SORT_PARAM *sort_param, const void *a,
|
||||
const void *b)
|
||||
{
|
||||
uint not_used;
|
||||
uint not_used[2];
|
||||
return (ha_key_cmp(sort_param->seg, *((uchar**) a), *((uchar**) b),
|
||||
USE_WHOLE_KEY, SEARCH_SAME,¬_used));
|
||||
USE_WHOLE_KEY, SEARCH_SAME, not_used));
|
||||
} /* sort_key_cmp */
|
||||
|
||||
|
||||
static int sort_key_write(MI_SORT_PARAM *sort_param, const void *a)
|
||||
{
|
||||
uint diff_pos;
|
||||
uint diff_pos[2];
|
||||
char llbuff[22],llbuff2[22];
|
||||
SORT_INFO *sort_info=sort_param->sort_info;
|
||||
MI_CHECK *param= sort_info->param;
|
||||
@ -3250,16 +3359,26 @@ static int sort_key_write(MI_SORT_PARAM *sort_param, const void *a)
|
||||
{
|
||||
cmp=ha_key_cmp(sort_param->seg,sort_info->key_block->lastkey,
|
||||
(uchar*) a, USE_WHOLE_KEY,SEARCH_FIND | SEARCH_UPDATE,
|
||||
&diff_pos);
|
||||
diff_pos);
|
||||
if (param->stats_method == MI_STATS_METHOD_NULLS_NOT_EQUAL)
|
||||
ha_key_cmp(sort_param->seg,sort_info->key_block->lastkey,
|
||||
(uchar*) a, USE_WHOLE_KEY,
|
||||
SEARCH_FIND | SEARCH_NULL_ARE_NOT_EQUAL, &diff_pos);
|
||||
sort_param->unique[diff_pos-1]++;
|
||||
SEARCH_FIND | SEARCH_NULL_ARE_NOT_EQUAL, diff_pos);
|
||||
else if (param->stats_method == MI_STATS_METHOD_IGNORE_NULLS)
|
||||
{
|
||||
diff_pos[0]= mi_collect_stats_nonulls_next(sort_param->seg,
|
||||
sort_param->notnull,
|
||||
sort_info->key_block->lastkey,
|
||||
(uchar*)a);
|
||||
}
|
||||
sort_param->unique[diff_pos[0]-1]++;
|
||||
}
|
||||
else
|
||||
{
|
||||
cmp= -1;
|
||||
if (param->stats_method == MI_STATS_METHOD_IGNORE_NULLS)
|
||||
mi_collect_stats_nonulls_first(sort_param->seg, sort_param->notnull,
|
||||
(uchar*)a);
|
||||
}
|
||||
if ((sort_param->keyinfo->flag & HA_NOSAME) && cmp == 0)
|
||||
{
|
||||
@ -3978,24 +4097,34 @@ void update_auto_increment_key(MI_CHECK *param, MI_INFO *info,
|
||||
|
||||
/*
|
||||
Update statistics for each part of an index
|
||||
|
||||
|
||||
SYNOPSIS
|
||||
update_key_parts()
|
||||
keyinfo Index information (only key->keysegs used)
|
||||
keyinfo IN Index information (only key->keysegs used)
|
||||
rec_per_key_part OUT Store statistics here
|
||||
unique IN Array of #distinct values collected over index
|
||||
run.
|
||||
unique IN Array of (#distinct tuples)
|
||||
notnull_tuples IN Array of (#tuples), or NULL
|
||||
records Number of records in the table
|
||||
|
||||
NOTES
|
||||
|
||||
DESCRIPTION
|
||||
This function is called produce index statistics values from unique and
|
||||
notnull_tuples arrays after these arrays were produced with sequential
|
||||
index scan (the scan is done in two places: chk_index() and
|
||||
sort_key_write()).
|
||||
|
||||
This function handles all 3 index statistics collection methods.
|
||||
|
||||
Unique is an array:
|
||||
unique[0]= (#different values of {keypart1}) - 1
|
||||
unique[1]= (#different values of {keypart2,keypart1} tuple) - unique[0] - 1
|
||||
...
|
||||
The 'unique' array is collected in one sequential scan through the entire
|
||||
index. This is done in two places: in chk_index() and in sort_key_write().
|
||||
Statistics collection may consider NULLs as either equal or unequal (see
|
||||
SEARCH_NULL_ARE_NOT_EQUAL, MI_STATS_METHOD_*).
|
||||
unique[0]= (#different values of {keypart1}) - 1
|
||||
unique[1]= (#different values of {keypart1,keypart2} tuple)-unique[0]-1
|
||||
...
|
||||
|
||||
For MI_STATS_METHOD_IGNORE_NULLS method, notnull_tuples is an array too:
|
||||
notnull_tuples[0]= (#of {keypart1} tuples such that keypart1 is not NULL)
|
||||
notnull_tuples[1]= (#of {keypart1,keypart2} tuples such that all
|
||||
keypart{i} are not NULL)
|
||||
...
|
||||
For all other statistics collection methods notnull_tuples==NULL.
|
||||
|
||||
Output is an array:
|
||||
rec_per_key_part[k] =
|
||||
@ -4007,25 +4136,53 @@ void update_auto_increment_key(MI_CHECK *param, MI_INFO *info,
|
||||
index tuples}
|
||||
|
||||
= #tuples-in-the-index / #distinct-tuples-in-the-index.
|
||||
|
||||
The #tuples-in-the-index and #distinct-tuples-in-the-index have different
|
||||
meaning depending on which statistics collection method is used:
|
||||
|
||||
MI_STATS_METHOD_* how are nulls compared? which tuples are counted?
|
||||
NULLS_EQUAL NULL == NULL all tuples in table
|
||||
NULLS_NOT_EQUAL NULL != NULL all tuples in table
|
||||
IGNORE_NULLS n/a tuples that don't have NULLs
|
||||
*/
|
||||
|
||||
void update_key_parts(MI_KEYDEF *keyinfo, ulong *rec_per_key_part,
|
||||
ulonglong *unique, ulonglong records)
|
||||
ulonglong *unique, ulonglong *notnull,
|
||||
ulonglong records)
|
||||
{
|
||||
ulonglong count=0,tmp;
|
||||
ulonglong count=0,tmp, unique_tuples;
|
||||
ulonglong tuples= records;
|
||||
uint parts;
|
||||
for (parts=0 ; parts < keyinfo->keysegs ; parts++)
|
||||
{
|
||||
count+=unique[parts];
|
||||
if (count == 0)
|
||||
tmp=records;
|
||||
unique_tuples= count + 1;
|
||||
if (notnull)
|
||||
{
|
||||
tuples= notnull[parts];
|
||||
/*
|
||||
#(unique_tuples not counting tuples with NULLs) =
|
||||
#(unique_tuples counting tuples with NULLs as different) -
|
||||
#(tuples with NULLs)
|
||||
*/
|
||||
unique_tuples -= (records - notnull[parts]);
|
||||
}
|
||||
|
||||
if (unique_tuples == 0)
|
||||
tmp= 1;
|
||||
else if (count == 0)
|
||||
tmp= tuples; /* 1 unique tuple */
|
||||
else
|
||||
tmp= (records + (count+1)/2) / (count+1);
|
||||
/* for some weird keys (e.g. FULLTEXT) tmp can be <1 here.
|
||||
let's ensure it is not */
|
||||
tmp= (tuples + unique_tuples/2) / unique_tuples;
|
||||
|
||||
/*
|
||||
for some weird keys (e.g. FULLTEXT) tmp can be <1 here.
|
||||
let's ensure it is not
|
||||
*/
|
||||
set_if_bigger(tmp,1);
|
||||
if (tmp >= (ulonglong) ~(ulong) 0)
|
||||
tmp=(ulonglong) ~(ulong) 0;
|
||||
|
||||
*rec_per_key_part=(ulong) tmp;
|
||||
rec_per_key_part++;
|
||||
}
|
||||
|
@ -390,7 +390,8 @@ static int del(register MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *key,
|
||||
MYISAM_SHARE *share=info->s;
|
||||
MI_KEY_PARAM s_temp;
|
||||
DBUG_ENTER("del");
|
||||
DBUG_PRINT("enter",("leaf_page: %ld keypos: %lx",leaf_page,keypos));
|
||||
DBUG_PRINT("enter",("leaf_page: %ld keypos: 0x%lx", leaf_page,
|
||||
(ulong) keypos));
|
||||
DBUG_DUMP("leaf_buff",(byte*) leaf_buff,mi_getint(leaf_buff));
|
||||
|
||||
endpos=leaf_buff+mi_getint(leaf_buff);
|
||||
@ -495,7 +496,8 @@ static int underflow(register MI_INFO *info, register MI_KEYDEF *keyinfo,
|
||||
MI_KEY_PARAM s_temp;
|
||||
MYISAM_SHARE *share=info->s;
|
||||
DBUG_ENTER("underflow");
|
||||
DBUG_PRINT("enter",("leaf_page: %ld keypos: %lx",(long) leaf_page,keypos));
|
||||
DBUG_PRINT("enter",("leaf_page: %ld keypos: 0x%lx",(long) leaf_page,
|
||||
(ulong) keypos));
|
||||
DBUG_DUMP("anc_buff",(byte*) anc_buff,mi_getint(anc_buff));
|
||||
DBUG_DUMP("leaf_buff",(byte*) leaf_buff,mi_getint(leaf_buff));
|
||||
|
||||
|
@ -28,7 +28,7 @@
|
||||
int mi_rnext_same(MI_INFO *info, byte *buf)
|
||||
{
|
||||
int error;
|
||||
uint inx,not_used;
|
||||
uint inx,not_used[2];
|
||||
MI_KEYDEF *keyinfo;
|
||||
DBUG_ENTER("mi_rnext_same");
|
||||
|
||||
@ -69,7 +69,7 @@ int mi_rnext_same(MI_INFO *info, byte *buf)
|
||||
info->s->state.key_root[inx])))
|
||||
break;
|
||||
if (ha_key_cmp(keyinfo->seg, info->lastkey, info->lastkey2,
|
||||
info->last_rkey_length, SEARCH_FIND, ¬_used))
|
||||
info->last_rkey_length, SEARCH_FIND, not_used))
|
||||
{
|
||||
error=1;
|
||||
my_errno=HA_ERR_END_OF_FILE;
|
||||
|
@ -128,13 +128,13 @@ int _mi_search(register MI_INFO *info, register MI_KEYDEF *keyinfo,
|
||||
|
||||
if ((nextflag & (SEARCH_SMALLER | SEARCH_LAST)) && flag != 0)
|
||||
{
|
||||
uint not_used;
|
||||
uint not_used[2];
|
||||
if (_mi_get_prev_key(info,keyinfo, buff, info->lastkey, keypos,
|
||||
&info->lastkey_length))
|
||||
goto err;
|
||||
if (!(nextflag & SEARCH_SMALLER) &&
|
||||
ha_key_cmp(keyinfo->seg, info->lastkey, key, key_len, SEARCH_FIND,
|
||||
¬_used))
|
||||
not_used))
|
||||
{
|
||||
my_errno=HA_ERR_KEY_NOT_FOUND; /* Didn't find key */
|
||||
goto err;
|
||||
@ -178,7 +178,7 @@ int _mi_bin_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page,
|
||||
{
|
||||
reg4 int start,mid,end,save_end;
|
||||
int flag;
|
||||
uint totlength,nod_flag,not_used;
|
||||
uint totlength,nod_flag,not_used[2];
|
||||
DBUG_ENTER("_mi_bin_search");
|
||||
|
||||
LINT_INIT(flag);
|
||||
@ -192,7 +192,7 @@ int _mi_bin_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page,
|
||||
{
|
||||
mid= (start+end)/2;
|
||||
if ((flag=ha_key_cmp(keyinfo->seg,page+(uint) mid*totlength,key,key_len,
|
||||
comp_flag,¬_used))
|
||||
comp_flag, not_used))
|
||||
>= 0)
|
||||
end=mid;
|
||||
else
|
||||
@ -200,7 +200,7 @@ int _mi_bin_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page,
|
||||
}
|
||||
if (mid != start)
|
||||
flag=ha_key_cmp(keyinfo->seg,page+(uint) start*totlength,key,key_len,
|
||||
comp_flag,¬_used);
|
||||
comp_flag, not_used);
|
||||
if (flag < 0)
|
||||
start++; /* point at next, bigger key */
|
||||
*ret_pos=page+(uint) start*totlength;
|
||||
@ -241,7 +241,7 @@ int _mi_seq_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page,
|
||||
uchar *buff, my_bool *last_key)
|
||||
{
|
||||
int flag;
|
||||
uint nod_flag,length,not_used;
|
||||
uint nod_flag,length,not_used[2];
|
||||
uchar t_buff[MI_MAX_KEY_BUFF],*end;
|
||||
DBUG_ENTER("_mi_seq_search");
|
||||
|
||||
@ -262,7 +262,7 @@ int _mi_seq_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page,
|
||||
DBUG_RETURN(MI_FOUND_WRONG_KEY);
|
||||
}
|
||||
if ((flag=ha_key_cmp(keyinfo->seg,t_buff,key,key_len,comp_flag,
|
||||
¬_used)) >= 0)
|
||||
not_used)) >= 0)
|
||||
break;
|
||||
#ifdef EXTRA_DEBUG
|
||||
DBUG_PRINT("loop",("page: %lx key: '%s' flag: %d", (long) page, t_buff,
|
||||
@ -503,9 +503,9 @@ int _mi_prefix_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page,
|
||||
cmp_rest:
|
||||
if (key_len_left>0)
|
||||
{
|
||||
uint not_used;
|
||||
uint not_used[2];
|
||||
if ((flag = ha_key_cmp(keyinfo->seg+1,vseg,
|
||||
k,key_len_left,nextflag,¬_used)) >= 0)
|
||||
k, key_len_left, nextflag, not_used)) >= 0)
|
||||
break;
|
||||
}
|
||||
else
|
||||
|
@ -885,10 +885,10 @@ int _mi_ck_write_tree(register MI_INFO *info, uint keynr, uchar *key,
|
||||
|
||||
static int keys_compare(bulk_insert_param *param, uchar *key1, uchar *key2)
|
||||
{
|
||||
uint not_used;
|
||||
uint not_used[2];
|
||||
return ha_key_cmp(param->info->s->keyinfo[param->keynr].seg,
|
||||
key1, key2, USE_WHOLE_KEY, SEARCH_SAME,
|
||||
¬_used);
|
||||
key1, key2, USE_WHOLE_KEY, SEARCH_SAME,
|
||||
not_used);
|
||||
}
|
||||
|
||||
|
||||
|
@ -339,7 +339,8 @@ static struct my_option my_long_options[] =
|
||||
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
|
||||
{"stats_method", OPT_STATS_METHOD,
|
||||
"Specifies how index statistics collection code should threat NULLs. "
|
||||
"Possible values of name are \"nulls_unequal\" (default behavior for 4.1/5.0), and \"nulls_equal\" (emulate 4.0 behavior).",
|
||||
"Possible values of name are \"nulls_unequal\" (default behavior for 4.1/5.0), "
|
||||
"\"nulls_equal\" (emulate 4.0 behavior), and \"nulls_ignored\".",
|
||||
(gptr*) &myisam_stats_method_str, (gptr*) &myisam_stats_method_str, 0,
|
||||
GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
|
||||
{ 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
|
||||
@ -451,6 +452,10 @@ static void usage(void)
|
||||
-a, --analyze Analyze distribution of keys. Will make some joins in\n\
|
||||
MySQL faster. You can check the calculated distribution\n\
|
||||
by using '--description --verbose table_name'.\n\
|
||||
--stats_method=name Specifies how index statistics collection code should\n\
|
||||
threat NULLs. Possible values of name are \"nulls_unequal\"\n\
|
||||
(default for 4.1/5.0), \"nulls_equal\" (emulate 4.0), and \n\
|
||||
\"nulls_ignored\".\n\
|
||||
-d, --description Prints some information about table.\n\
|
||||
-A, --set-auto-increment[=value]\n\
|
||||
Force auto_increment to start at this or higher value\n\
|
||||
@ -472,7 +477,7 @@ static void usage(void)
|
||||
#include <help_end.h>
|
||||
|
||||
const char *myisam_stats_method_names[] = {"nulls_unequal", "nulls_equal",
|
||||
NullS};
|
||||
"nulls_ignored", NullS};
|
||||
TYPELIB myisam_stats_method_typelib= {
|
||||
array_elements(myisam_stats_method_names) - 1, "",
|
||||
myisam_stats_method_names, NULL};
|
||||
@ -699,14 +704,25 @@ get_one_option(int optid,
|
||||
case OPT_STATS_METHOD:
|
||||
{
|
||||
int method;
|
||||
enum_mi_stats_method method_conv;
|
||||
myisam_stats_method_str= argument;
|
||||
if ((method=find_type(argument, &myisam_stats_method_typelib, 2)) <= 0)
|
||||
{
|
||||
fprintf(stderr, "Invalid value of stats_method: %s.\n", argument);
|
||||
exit(1);
|
||||
}
|
||||
check_param.stats_method= test(method-1)? MI_STATS_METHOD_NULLS_EQUAL :
|
||||
MI_STATS_METHOD_NULLS_NOT_EQUAL;
|
||||
switch (method-1) {
|
||||
case 0:
|
||||
method_conv= MI_STATS_METHOD_NULLS_EQUAL;
|
||||
break;
|
||||
case 1:
|
||||
method_conv= MI_STATS_METHOD_NULLS_NOT_EQUAL;
|
||||
break;
|
||||
case 2:
|
||||
method_conv= MI_STATS_METHOD_IGNORE_NULLS;
|
||||
break;
|
||||
}
|
||||
check_param.stats_method= method_conv;
|
||||
break;
|
||||
}
|
||||
#ifdef DEBUG /* Only useful if debugging */
|
||||
|
@ -297,7 +297,14 @@ typedef struct st_mi_sort_param
|
||||
pthread_t thr;
|
||||
IO_CACHE read_cache, tempfile, tempfile_for_exceptions;
|
||||
DYNAMIC_ARRAY buffpek;
|
||||
|
||||
/*
|
||||
The next two are used to collect statistics, see update_key_parts for
|
||||
description.
|
||||
*/
|
||||
ulonglong unique[MI_MAX_KEY_SEG+1];
|
||||
ulonglong notnull[MI_MAX_KEY_SEG+1];
|
||||
|
||||
my_off_t pos,max_pos,filepos,start_recpos;
|
||||
uint key, key_length,real_key_length,sortbuff_size;
|
||||
uint maxbuffers, keys, find_length, sort_keys_length;
|
||||
|
@ -481,8 +481,12 @@ int thr_write_keys(MI_SORT_PARAM *sort_param)
|
||||
{
|
||||
share->state.key_map|=(ulonglong) 1 << sinfo->key;
|
||||
if (param->testflag & T_STATISTICS)
|
||||
update_key_parts(sinfo->keyinfo, rec_per_key_part,
|
||||
sinfo->unique, (ulonglong) info->state->records);
|
||||
update_key_parts(sinfo->keyinfo, rec_per_key_part, sinfo->unique,
|
||||
param->stats_method == MI_STATS_METHOD_IGNORE_NULLS?
|
||||
sinfo->notnull: NULL,
|
||||
(ulonglong) info->state->records);
|
||||
|
||||
|
||||
if (!sinfo->buffpek.elements)
|
||||
{
|
||||
if (param->testflag & T_VERBOSE)
|
||||
|
@ -20,9 +20,9 @@ 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;
|
||||
uint not_used[2];
|
||||
int ret= ha_key_cmp((HA_KEYSEG *)keyseg, aa->lastkey, bb->lastkey,
|
||||
USE_WHOLE_KEY, SEARCH_FIND, ¬_used);
|
||||
USE_WHOLE_KEY, SEARCH_FIND, not_used);
|
||||
return ret < 0 ? -1 : ret > 0 ? 1 : 0;
|
||||
} /* queue_key_cmp */
|
||||
|
||||
|
@ -230,7 +230,10 @@ int wait_for_server_start(char *bin_dir __attribute__((unused)),
|
||||
char *user, char *password, int port,char *tmp_dir)
|
||||
{
|
||||
arg_list_t al;
|
||||
int err= 0, i;
|
||||
int err= 0;
|
||||
#ifndef __WIN__
|
||||
int i;
|
||||
#endif
|
||||
char trash[FN_REFLEN];
|
||||
|
||||
/* mysqladmin file */
|
||||
|
@ -462,6 +462,13 @@ sub command_line_setup () {
|
||||
my $opt_slave_myport= 9308;
|
||||
$opt_ndbcluster_port= 9350;
|
||||
|
||||
if ( $ENV{'MTR_BUILD_THREAD'} )
|
||||
{
|
||||
$opt_master_myport= $ENV{'MTR_BUILD_THREAD'} * 40 + 8120;
|
||||
$opt_slave_myport= $opt_master_myport + 16;
|
||||
$opt_ndbcluster_port= $opt_master_myport + 24;
|
||||
}
|
||||
|
||||
# Read the command line
|
||||
# Note: Keep list, and the order, in sync with usage at end of this file
|
||||
|
||||
@ -833,7 +840,9 @@ sub executable_setup () {
|
||||
{
|
||||
$path_client_bindir= mtr_path_exists("$glob_basedir/client_release",
|
||||
"$glob_basedir/bin");
|
||||
$exe_mysqld= mtr_exe_exists ("$path_client_bindir/mysqld-nt");
|
||||
$exe_mysqld= mtr_exe_exists ("$path_client_bindir/mysqld-nt",
|
||||
"$path_client_bindir/mysqld",
|
||||
"$path_client_bindir/mysqld-debug",);
|
||||
$path_language= mtr_path_exists("$glob_basedir/share/english/");
|
||||
$path_charsetsdir= mtr_path_exists("$glob_basedir/share/charsets");
|
||||
}
|
||||
@ -886,8 +895,18 @@ sub executable_setup () {
|
||||
"$glob_basedir/share/english/");
|
||||
$path_charsetsdir= mtr_path_exists("$glob_basedir/share/mysql/charsets",
|
||||
"$glob_basedir/share/charsets");
|
||||
$exe_mysqld= mtr_exe_exists ("$glob_basedir/libexec/mysqld",
|
||||
"$glob_basedir/bin/mysqld");
|
||||
|
||||
if ( $glob_win32 )
|
||||
{
|
||||
$exe_mysqld= mtr_exe_exists ("$glob_basedir/bin/mysqld-nt",
|
||||
"$glob_basedir/bin/mysqld",
|
||||
"$glob_basedir/bin/mysqld-debug",);
|
||||
}
|
||||
else
|
||||
{
|
||||
$exe_mysqld= mtr_exe_exists ("$glob_basedir/libexec/mysqld",
|
||||
"$glob_basedir/bin/mysqld");
|
||||
}
|
||||
|
||||
if ( $glob_use_embedded_server )
|
||||
{
|
||||
@ -971,6 +990,13 @@ sub environment_setup () {
|
||||
chomp($ENV{$key});
|
||||
}
|
||||
}
|
||||
|
||||
# We are nice and report a bit about our settings
|
||||
print "Using MTR_BUILD_THREAD = ",$ENV{MTR_BUILD_THREAD} || 0,"\n";
|
||||
print "Using MASTER_MYPORT = $ENV{MASTER_MYPORT}\n";
|
||||
print "Using MASTER_MYPORT1 = $ENV{MASTER_MYPORT1}\n";
|
||||
print "Using SLAVE_MYPORT = $ENV{SLAVE_MYPORT}\n";
|
||||
print "Using NDBCLUSTER_PORT = $opt_ndbcluster_port\n";
|
||||
}
|
||||
|
||||
|
||||
|
@ -209,6 +209,25 @@ NDBCLUSTER_PORT=9350
|
||||
MYSQL_MANAGER_PW_FILE=$MYSQL_TEST_DIR/var/tmp/manager.pwd
|
||||
MYSQL_MANAGER_LOG=$MYSQL_TEST_DIR/var/log/manager.log
|
||||
MYSQL_MANAGER_USER=root
|
||||
|
||||
#
|
||||
# To make it easier for different devs to work on the same host,
|
||||
# an environment variable can be used to control all ports. A small
|
||||
# number is to be used, 0 - 16 or similar.
|
||||
#
|
||||
if [ -n "$MTR_BUILD_THREAD" ] ; then
|
||||
MASTER_MYPORT=`expr $MTR_BUILD_THREAD '*' 40 + 8120`
|
||||
MYSQL_MANAGER_PORT=`expr $MASTER_MYPORT + 2`
|
||||
SLAVE_MYPORT=`expr $MASTER_MYPORT + 16`
|
||||
NDBCLUSTER_PORT=`expr $MASTER_MYPORT + 24`
|
||||
|
||||
echo "Using MTR_BUILD_THREAD = $MTR_BUILD_THREAD"
|
||||
echo "Using MASTER_MYPORT = $MASTER_MYPORT"
|
||||
echo "Using MYSQL_MANAGER_PORT = $MYSQL_MANAGER_PORT"
|
||||
echo "Using SLAVE_MYPORT = $SLAVE_MYPORT"
|
||||
echo "Using NDBCLUSTER_PORT = $NDBCLUSTER_PORT"
|
||||
fi
|
||||
|
||||
NO_SLAVE=0
|
||||
USER_TEST=
|
||||
FAILED_CASES=
|
||||
|
@ -1716,7 +1716,6 @@ int main(int argc, char **argv)
|
||||
int* handle;
|
||||
char test[FN_LEN];
|
||||
char mask[FN_REFLEN];
|
||||
char *p;
|
||||
int position;
|
||||
|
||||
/* single test */
|
||||
|
@ -19,3 +19,26 @@ SELECT * FROM t1 WHERE popisek LIKE '2005-01-1';
|
||||
popisek
|
||||
2005-01-1
|
||||
drop table t1;
|
||||
set names cp1250;
|
||||
CREATE TABLE t1
|
||||
(
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
str VARCHAR(32) CHARACTER SET cp1250 COLLATE cp1250_czech_cs NOT NULL default '',
|
||||
UNIQUE KEY (str)
|
||||
);
|
||||
INSERT INTO t1 VALUES (NULL, 'a');
|
||||
INSERT INTO t1 VALUES (NULL, 'aa');
|
||||
INSERT INTO t1 VALUES (NULL, 'aaa');
|
||||
INSERT INTO t1 VALUES (NULL, 'aaaa');
|
||||
INSERT INTO t1 VALUES (NULL, 'aaaaa');
|
||||
INSERT INTO t1 VALUES (NULL, 'aaaaaa');
|
||||
INSERT INTO t1 VALUES (NULL, 'aaaaaaa');
|
||||
select * from t1 where str like 'aa%';
|
||||
id str
|
||||
2 aa
|
||||
3 aaa
|
||||
4 aaaa
|
||||
5 aaaaa
|
||||
6 aaaaaa
|
||||
7 aaaaaaa
|
||||
drop table t1;
|
||||
|
@ -1061,3 +1061,12 @@ create table t1 (a varchar(255)) default charset=utf8;
|
||||
select * from t1 where find_in_set('-1', a);
|
||||
a
|
||||
drop table t1;
|
||||
create table t1 (a int);
|
||||
insert into t1 values (48),(49),(50);
|
||||
set names utf8;
|
||||
select distinct char(a) from t1;
|
||||
char(a)
|
||||
0
|
||||
1
|
||||
2
|
||||
drop table t1;
|
||||
|
@ -456,3 +456,11 @@ f1 f2
|
||||
Warnings:
|
||||
Warning 1292 Truncated incorrect date value: '2003-04-05 g'
|
||||
Warning 1292 Truncated incorrect datetime value: '2003-04-05 10:11:12.101010234567'
|
||||
create table t1 (f1 datetime);
|
||||
insert into t1 (f1) values ("2005-01-01");
|
||||
insert into t1 (f1) values ("2005-02-01");
|
||||
select date_format(f1, "%m") as d1, date_format(f1, "%M") as d2 from t1 order by date_format(f1, "%M");
|
||||
d1 d2
|
||||
02 February
|
||||
01 January
|
||||
drop table t1;
|
||||
|
@ -678,3 +678,11 @@ f1
|
||||
2001
|
||||
2002
|
||||
drop table t1;
|
||||
create table t1(x int, y int);
|
||||
create table t2(x int, z int);
|
||||
insert into t1(x,y) select x,z from t2 on duplicate key update x=values(x);
|
||||
insert into t1(x,y) select x,z from t2 on duplicate key update x=values(z);
|
||||
ERROR 42S22: Unknown column 'z' in 'field list'
|
||||
insert into t1(x,y) select x,z from t2 on duplicate key update x=values(t2.x);
|
||||
ERROR 42S02: Unknown table 't2' in field list
|
||||
drop table t1,t2;
|
||||
|
@ -76,3 +76,12 @@ select * from t1;
|
||||
id
|
||||
0
|
||||
SET @@SQL_MODE=@OLD_SQL_MODE;
|
||||
drop table t1;
|
||||
create table t1 (a varchar(20), b varchar(20));
|
||||
load data infile '../../std_data/loaddata5.dat' into table t1 fields terminated by ',' enclosed by '"' escaped by '"' (a,b);
|
||||
select * from t1;
|
||||
a b
|
||||
field1 field2
|
||||
a"b cd"ef
|
||||
a"b c"d"e
|
||||
drop table t1;
|
||||
|
@ -670,3 +670,35 @@ show index from t1;
|
||||
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
|
||||
t1 1 a 1 a A 10 NULL NULL YES BTREE
|
||||
drop table t1;
|
||||
set myisam_stats_method=nulls_ignored;
|
||||
show variables like 'myisam_stats_method';
|
||||
Variable_name Value
|
||||
myisam_stats_method nulls_ignored
|
||||
create table t1 (
|
||||
a char(3), b char(4), c char(5), d char(6),
|
||||
key(a,b,c,d)
|
||||
);
|
||||
insert into t1 values ('bcd','def1', NULL, 'zz');
|
||||
insert into t1 values ('bcd','def2', NULL, 'zz');
|
||||
insert into t1 values ('bce','def1', 'yuu', NULL);
|
||||
insert into t1 values ('bce','def2', NULL, 'quux');
|
||||
analyze table t1;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t1 analyze status OK
|
||||
show index from t1;
|
||||
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
|
||||
t1 1 a 1 a A 2 NULL NULL YES BTREE
|
||||
t1 1 a 2 b A 4 NULL NULL YES BTREE
|
||||
t1 1 a 3 c A 4 NULL NULL YES BTREE
|
||||
t1 1 a 4 d A 4 NULL NULL YES BTREE
|
||||
delete from t1;
|
||||
analyze table t1;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t1 analyze status OK
|
||||
show index from t1;
|
||||
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
|
||||
t1 1 a 1 a A 0 NULL NULL YES BTREE
|
||||
t1 1 a 2 b A 0 NULL NULL YES BTREE
|
||||
t1 1 a 3 c A 0 NULL NULL YES BTREE
|
||||
t1 1 a 4 d A 0 NULL NULL YES BTREE
|
||||
set myisam_stats_method=DEFAULT;
|
||||
|
@ -2698,3 +2698,11 @@ a b c d
|
||||
1 2 2 1
|
||||
1 2 3 1
|
||||
DROP TABLE IF EXISTS t1, t2;
|
||||
create table t1 (f1 int primary key, f2 int);
|
||||
create table t2 (f3 int, f4 int, primary key(f3,f4));
|
||||
insert into t1 values (1,1);
|
||||
insert into t2 values (1,1),(1,2);
|
||||
select distinct count(f2) >0 from t1 left join t2 on f1=f3 group by f1;
|
||||
count(f2) >0
|
||||
1
|
||||
drop table t1,t2;
|
||||
|
@ -513,3 +513,10 @@ t1 CREATE TABLE `t1` (
|
||||
KEY `c2` USING BTREE (`c2`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
DROP TABLE t1;
|
||||
flush tables;
|
||||
SHOW TABLE STATUS like 't1';
|
||||
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
|
||||
t1 NULL NULL NULL NULL # # # # NULL NULL NULL NULL NULL NULL NULL NULL Incorrect information in file: './test/t1.frm'
|
||||
show create table t1;
|
||||
ERROR HY000: Incorrect information in file: './test/t1.frm'
|
||||
drop table t1;
|
||||
|
@ -263,3 +263,77 @@ test
|
||||
delete from t1 where count(*)=1;
|
||||
ERROR HY000: Invalid use of group function
|
||||
drop table t1;
|
||||
create table t1 ( a int, b int default 0, index (a) );
|
||||
insert into t1 (a) values (0),(0),(0),(0),(0),(0),(0),(0);
|
||||
flush status;
|
||||
select a from t1 order by a limit 1;
|
||||
a
|
||||
0
|
||||
show status like 'handler_read%';
|
||||
Variable_name Value
|
||||
Handler_read_first 1
|
||||
Handler_read_key 0
|
||||
Handler_read_next 0
|
||||
Handler_read_prev 0
|
||||
Handler_read_rnd 0
|
||||
Handler_read_rnd_next 0
|
||||
flush status;
|
||||
update t1 set a=9999 order by a limit 1;
|
||||
update t1 set b=9999 order by a limit 1;
|
||||
show status like 'handler_read%';
|
||||
Variable_name Value
|
||||
Handler_read_first 1
|
||||
Handler_read_key 0
|
||||
Handler_read_next 0
|
||||
Handler_read_prev 0
|
||||
Handler_read_rnd 2
|
||||
Handler_read_rnd_next 9
|
||||
flush status;
|
||||
delete from t1 order by a limit 1;
|
||||
show status like 'handler_read%';
|
||||
Variable_name Value
|
||||
Handler_read_first 1
|
||||
Handler_read_key 0
|
||||
Handler_read_next 0
|
||||
Handler_read_prev 0
|
||||
Handler_read_rnd 0
|
||||
Handler_read_rnd_next 0
|
||||
flush status;
|
||||
delete from t1 order by a desc limit 1;
|
||||
show status like 'handler_read%';
|
||||
Variable_name Value
|
||||
Handler_read_first 0
|
||||
Handler_read_key 0
|
||||
Handler_read_next 0
|
||||
Handler_read_prev 0
|
||||
Handler_read_rnd 1
|
||||
Handler_read_rnd_next 9
|
||||
alter table t1 disable keys;
|
||||
flush status;
|
||||
delete from t1 order by a limit 1;
|
||||
show status like 'handler_read%';
|
||||
Variable_name Value
|
||||
Handler_read_first 0
|
||||
Handler_read_key 0
|
||||
Handler_read_next 0
|
||||
Handler_read_prev 0
|
||||
Handler_read_rnd 1
|
||||
Handler_read_rnd_next 9
|
||||
select * from t1;
|
||||
a b
|
||||
0 0
|
||||
0 0
|
||||
0 0
|
||||
0 0
|
||||
0 0
|
||||
update t1 set a=a+10,b=1 order by a limit 3;
|
||||
update t1 set a=a+11,b=2 order by a limit 3;
|
||||
update t1 set a=a+12,b=3 order by a limit 3;
|
||||
select * from t1 order by a;
|
||||
a b
|
||||
11 2
|
||||
21 2
|
||||
22 3
|
||||
22 3
|
||||
23 3
|
||||
drop table t1;
|
||||
|
@ -499,3 +499,8 @@ set names latin1;
|
||||
select @@have_innodb;
|
||||
@@have_innodb
|
||||
#
|
||||
set @test = @@query_prealloc_size;
|
||||
set @@query_prealloc_size = @test;
|
||||
select @@query_prealloc_size = @test;
|
||||
@@query_prealloc_size = @test
|
||||
1
|
||||
|
3
mysql-test/std_data/loaddata5.dat
Normal file
3
mysql-test/std_data/loaddata5.dat
Normal file
@ -0,0 +1,3 @@
|
||||
"field1","field2"
|
||||
"a""b","cd""ef"
|
||||
"a"b",c"d"e
|
@ -23,4 +23,25 @@ SELECT * FROM t1 WHERE popisek = '2005-01-1';
|
||||
SELECT * FROM t1 WHERE popisek LIKE '2005-01-1';
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# Bug#13347: empty result from query with like and cp1250 charset
|
||||
#
|
||||
set names cp1250;
|
||||
CREATE TABLE t1
|
||||
(
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
str VARCHAR(32) CHARACTER SET cp1250 COLLATE cp1250_czech_cs NOT NULL default '',
|
||||
UNIQUE KEY (str)
|
||||
);
|
||||
|
||||
INSERT INTO t1 VALUES (NULL, 'a');
|
||||
INSERT INTO t1 VALUES (NULL, 'aa');
|
||||
INSERT INTO t1 VALUES (NULL, 'aaa');
|
||||
INSERT INTO t1 VALUES (NULL, 'aaaa');
|
||||
INSERT INTO t1 VALUES (NULL, 'aaaaa');
|
||||
INSERT INTO t1 VALUES (NULL, 'aaaaaa');
|
||||
INSERT INTO t1 VALUES (NULL, 'aaaaaaa');
|
||||
select * from t1 where str like 'aa%';
|
||||
drop table t1;
|
||||
|
||||
# End of 4.1 tests
|
||||
|
@ -873,4 +873,13 @@ create table t1 (a varchar(255)) default charset=utf8;
|
||||
select * from t1 where find_in_set('-1', a);
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# Bug#13233: select distinct char(column) fails with utf8
|
||||
#
|
||||
create table t1 (a int);
|
||||
insert into t1 values (48),(49),(50);
|
||||
set names utf8;
|
||||
select distinct char(a) from t1;
|
||||
drop table t1;
|
||||
|
||||
# End of 4.1 tests
|
||||
|
@ -260,4 +260,12 @@ select str_to_date("2003-04-05 g", "%Y-%m-%d") as f1,
|
||||
str_to_date("2003-04-05 10:11:12.101010234567", "%Y-%m-%d %H:%i:%S.%f") as f2;
|
||||
--enable_ps_protocol
|
||||
|
||||
#
|
||||
# Bug #14016
|
||||
#
|
||||
create table t1 (f1 datetime);
|
||||
insert into t1 (f1) values ("2005-01-01");
|
||||
insert into t1 (f1) values ("2005-02-01");
|
||||
select date_format(f1, "%m") as d1, date_format(f1, "%M") as d2 from t1 order by date_format(f1, "%M");
|
||||
drop table t1;
|
||||
# End of 4.1 tests
|
||||
|
@ -214,4 +214,16 @@ insert into t1(f1) select if(max(f1) is null, '2000',max(f1)+1) from t1;
|
||||
select * from t1;
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# Bug #13392 values() fails with 'ambiguous' or returns NULL
|
||||
# with ON DUPLICATE and SELECT
|
||||
create table t1(x int, y int);
|
||||
create table t2(x int, z int);
|
||||
insert into t1(x,y) select x,z from t2 on duplicate key update x=values(x);
|
||||
--error 1054
|
||||
insert into t1(x,y) select x,z from t2 on duplicate key update x=values(z);
|
||||
--error 1109
|
||||
insert into t1(x,y) select x,z from t2 on duplicate key update x=values(t2.x);
|
||||
drop table t1,t2;
|
||||
|
||||
# End of 4.1 tests
|
||||
|
@ -31,7 +31,6 @@ load data infile '../../std_data/loaddata4.dat' into table t1 fields terminated
|
||||
select * from t1;
|
||||
drop table t1;
|
||||
|
||||
|
||||
#
|
||||
# Bug #12053 LOAD DATA INFILE ignores NO_AUTO_VALUE_ON_ZERO setting
|
||||
#
|
||||
@ -57,5 +56,15 @@ enable_query_log;
|
||||
select * from t1;
|
||||
--exec rm $MYSQL_TEST_DIR/var/tmp/t1
|
||||
SET @@SQL_MODE=@OLD_SQL_MODE;
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# Bug #11203: LOAD DATA does not accept same characters for ESCAPED and
|
||||
# ENCLOSED
|
||||
#
|
||||
create table t1 (a varchar(20), b varchar(20));
|
||||
load data infile '../../std_data/loaddata5.dat' into table t1 fields terminated by ',' enclosed by '"' escaped by '"' (a,b);
|
||||
select * from t1;
|
||||
drop table t1;
|
||||
|
||||
# End of 4.1 tests
|
||||
|
@ -637,4 +637,23 @@ show index from t1;
|
||||
|
||||
drop table t1;
|
||||
|
||||
# WL#2609, CSC#XXXX: MyISAM
|
||||
set myisam_stats_method=nulls_ignored;
|
||||
show variables like 'myisam_stats_method';
|
||||
|
||||
create table t1 (
|
||||
a char(3), b char(4), c char(5), d char(6),
|
||||
key(a,b,c,d)
|
||||
);
|
||||
insert into t1 values ('bcd','def1', NULL, 'zz');
|
||||
insert into t1 values ('bcd','def2', NULL, 'zz');
|
||||
insert into t1 values ('bce','def1', 'yuu', NULL);
|
||||
insert into t1 values ('bce','def2', NULL, 'quux');
|
||||
analyze table t1;
|
||||
show index from t1;
|
||||
delete from t1;
|
||||
analyze table t1;
|
||||
show index from t1;
|
||||
|
||||
set myisam_stats_method=DEFAULT;
|
||||
# End of 4.1 tests
|
||||
|
@ -6,7 +6,7 @@
|
||||
# var/log/mysql_client_test.trace
|
||||
|
||||
--disable_result_log
|
||||
--exec echo $MYSQL_CLIENT_TEST
|
||||
--exec $MYSQL_CLIENT_TEST
|
||||
--exec echo $MYSQL_CLIENT_TEST --getopt-ll-test=25600M
|
||||
--exec $MYSQL_CLIENT_TEST --getopt-ll-test=25600M
|
||||
|
||||
# End of 4.1 tests
|
||||
|
@ -2228,4 +2228,13 @@ SELECT t2.a, t2.b, IF(t1.b IS NULL,'',c) AS c, COUNT(*) AS d FROM t2,t1
|
||||
WHERE t2.a = t1.a AND t2.b = t1.b GROUP BY a, b, c;
|
||||
DROP TABLE IF EXISTS t1, t2;
|
||||
|
||||
#
|
||||
# Bug #13855 select distinct with group by caused server crash
|
||||
#
|
||||
create table t1 (f1 int primary key, f2 int);
|
||||
create table t2 (f3 int, f4 int, primary key(f3,f4));
|
||||
insert into t1 values (1,1);
|
||||
insert into t2 values (1,1),(1,2);
|
||||
select distinct count(f2) >0 from t1 left join t2 on f1=f3 group by f1;
|
||||
drop table t1,t2;
|
||||
# End of 4.1 tests
|
||||
|
@ -378,4 +378,17 @@ create table t1 (
|
||||
SHOW CREATE TABLE t1;
|
||||
DROP TABLE t1;
|
||||
|
||||
# Test for BUG#93: 4.1 protocl crash on corupted frm and SHOW TABLE STATUS
|
||||
|
||||
flush tables;
|
||||
|
||||
# Create a junk frm file on disk
|
||||
system echo "this is a junk file for test" >> var/master-data/test/t1.frm ;
|
||||
--replace_column 6 # 7 # 8 # 9 #
|
||||
SHOW TABLE STATUS like 't1';
|
||||
--error 1033
|
||||
show create table t1;
|
||||
drop table t1;
|
||||
|
||||
|
||||
# End of 4.1 tests
|
||||
|
@ -227,4 +227,38 @@ select DATABASE();
|
||||
delete from t1 where count(*)=1;
|
||||
drop table t1;
|
||||
|
||||
# BUG#12915: Optimize "DELETE|UPDATE ... ORDER BY ... LIMIT n" to use an index
|
||||
create table t1 ( a int, b int default 0, index (a) );
|
||||
insert into t1 (a) values (0),(0),(0),(0),(0),(0),(0),(0);
|
||||
|
||||
flush status;
|
||||
select a from t1 order by a limit 1;
|
||||
show status like 'handler_read%';
|
||||
|
||||
flush status;
|
||||
update t1 set a=9999 order by a limit 1;
|
||||
update t1 set b=9999 order by a limit 1;
|
||||
show status like 'handler_read%';
|
||||
|
||||
flush status;
|
||||
delete from t1 order by a limit 1;
|
||||
show status like 'handler_read%';
|
||||
|
||||
flush status;
|
||||
delete from t1 order by a desc limit 1;
|
||||
show status like 'handler_read%';
|
||||
|
||||
alter table t1 disable keys;
|
||||
|
||||
flush status;
|
||||
delete from t1 order by a limit 1;
|
||||
show status like 'handler_read%';
|
||||
|
||||
select * from t1;
|
||||
update t1 set a=a+10,b=1 order by a limit 3;
|
||||
update t1 set a=a+11,b=2 order by a limit 3;
|
||||
update t1 set a=a+12,b=3 order by a limit 3;
|
||||
select * from t1 order by a;
|
||||
|
||||
drop table t1;
|
||||
# End of 4.1 tests
|
||||
|
@ -388,7 +388,6 @@ set character_set_results=NULL;
|
||||
select ifnull(@@character_set_results,"really null");
|
||||
set names latin1;
|
||||
|
||||
# End of 4.1 tests
|
||||
|
||||
#
|
||||
# Bug #9613: @@have_innodb
|
||||
@ -396,3 +395,12 @@ set names latin1;
|
||||
|
||||
--replace_column 1 #
|
||||
select @@have_innodb;
|
||||
|
||||
#
|
||||
# Bug #13334: query_prealloc_size default less than minimum
|
||||
#
|
||||
set @test = @@query_prealloc_size;
|
||||
set @@query_prealloc_size = @test;
|
||||
select @@query_prealloc_size = @test;
|
||||
|
||||
# End of 4.1 tests
|
||||
|
@ -38,6 +38,22 @@ my_bool my_charset_same(CHARSET_INFO *cs1, CHARSET_INFO *cs2)
|
||||
}
|
||||
|
||||
|
||||
static uint
|
||||
get_collation_number_internal(const char *name)
|
||||
{
|
||||
CHARSET_INFO **cs;
|
||||
for (cs= all_charsets;
|
||||
cs < all_charsets+array_elements(all_charsets)-1 ;
|
||||
cs++)
|
||||
{
|
||||
if ( cs[0] && cs[0]->name &&
|
||||
!my_strcasecmp(&my_charset_latin1, cs[0]->name, name))
|
||||
return cs[0]->number;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static my_bool init_state_maps(CHARSET_INFO *cs)
|
||||
{
|
||||
uint i;
|
||||
@ -189,7 +205,8 @@ static my_bool simple_cs_is_full(CHARSET_INFO *cs)
|
||||
|
||||
static int add_collation(CHARSET_INFO *cs)
|
||||
{
|
||||
if (cs->name && (cs->number || (cs->number=get_collation_number(cs->name))))
|
||||
if (cs->name && (cs->number ||
|
||||
(cs->number=get_collation_number_internal(cs->name))))
|
||||
{
|
||||
if (!all_charsets[cs->number])
|
||||
{
|
||||
@ -419,18 +436,8 @@ void free_charsets(void)
|
||||
|
||||
uint get_collation_number(const char *name)
|
||||
{
|
||||
CHARSET_INFO **cs;
|
||||
init_available_charsets(MYF(0));
|
||||
|
||||
for (cs= all_charsets;
|
||||
cs < all_charsets+array_elements(all_charsets)-1 ;
|
||||
cs++)
|
||||
{
|
||||
if ( cs[0] && cs[0]->name &&
|
||||
!my_strcasecmp(&my_charset_latin1, cs[0]->name, name))
|
||||
return cs[0]->number;
|
||||
}
|
||||
return 0; /* this mimics find_type() */
|
||||
return get_collation_number_internal(name);
|
||||
}
|
||||
|
||||
|
||||
|
@ -689,10 +689,10 @@ static longlong getopt_ll(char *arg, const struct my_option *optp, int *err)
|
||||
ulonglong block_size= (optp->block_size ? (ulonglong) optp->block_size : 1L);
|
||||
|
||||
num= eval_num_suffix(arg, err, (char*) optp->name);
|
||||
if (num > 0 && (ulonglong) num > (ulonglong) (ulong) optp->max_value &&
|
||||
if (num > 0 && (ulonglong) num > (ulonglong) optp->max_value &&
|
||||
optp->max_value) /* if max value is not set -> no upper limit */
|
||||
num= (longlong) (ulong) optp->max_value;
|
||||
num= ((num - (longlong) optp->sub_size) / block_size);
|
||||
num= (ulonglong) optp->max_value;
|
||||
num= ((num - optp->sub_size) / block_size);
|
||||
num= (longlong) (num * block_size);
|
||||
return max(num, optp->min_value);
|
||||
}
|
||||
|
@ -75,7 +75,7 @@ static int compare_bin(uchar *a, uint a_length, uchar *b, uint b_length,
|
||||
|
||||
SYNOPSIS
|
||||
ha_key_cmp()
|
||||
keyseg Key segments of key to compare
|
||||
keyseg Array of key segments of key to compare
|
||||
a First key to compare, in format from _mi_pack_key()
|
||||
This is normally key specified by user
|
||||
b Second key to compare. This is always from a row
|
||||
@ -84,10 +84,26 @@ static int compare_bin(uchar *a, uint a_length, uchar *b, uint b_length,
|
||||
next_flag How keys should be compared
|
||||
If bit SEARCH_FIND is not set the keys includes the row
|
||||
position and this should also be compared
|
||||
diff_pos OUT Number of first keypart where values differ, counting
|
||||
from one.
|
||||
diff_pos[1] OUT (b + diff_pos[1]) points to first value in tuple b
|
||||
that is different from corresponding value in tuple a.
|
||||
|
||||
EXAMPLES
|
||||
Example1: if the function is called for tuples
|
||||
('aaa','bbb') and ('eee','fff'), then
|
||||
diff_pos[0] = 1 (as 'aaa' != 'eee')
|
||||
diff_pos[1] = 0 (offset from beggining of tuple b to 'eee' keypart).
|
||||
|
||||
Example2: if the index function is called for tuples
|
||||
('aaa','bbb') and ('aaa','fff'),
|
||||
diff_pos[0] = 2 (as 'aaa' != 'eee')
|
||||
diff_pos[1] = 3 (offset from beggining of tuple b to 'fff' keypart,
|
||||
here we assume that first key part is CHAR(3) NOT NULL)
|
||||
|
||||
NOTES
|
||||
Number-keys can't be splited
|
||||
|
||||
|
||||
RETURN VALUES
|
||||
<0 If a < b
|
||||
0 If a == b
|
||||
@ -107,6 +123,7 @@ int ha_key_cmp(register HA_KEYSEG *keyseg, register uchar *a,
|
||||
float f_1,f_2;
|
||||
double d_1,d_2;
|
||||
uint next_key_length;
|
||||
uchar *orig_b= b;
|
||||
|
||||
*diff_pos=0;
|
||||
for ( ; (int) key_length >0 ; key_length=next_key_length, keyseg++)
|
||||
@ -114,6 +131,7 @@ int ha_key_cmp(register HA_KEYSEG *keyseg, register uchar *a,
|
||||
uchar *end;
|
||||
uint piks=! (keyseg->flag & HA_NO_SORT);
|
||||
(*diff_pos)++;
|
||||
diff_pos[1]= (uint)(b - orig_b);
|
||||
|
||||
/* Handle NULL part */
|
||||
if (keyseg->null_bit)
|
||||
@ -448,3 +466,84 @@ end:
|
||||
}
|
||||
return 0;
|
||||
} /* ha_key_cmp */
|
||||
|
||||
|
||||
/*
|
||||
Find the first NULL value in index-suffix values tuple
|
||||
|
||||
SYNOPSIS
|
||||
ha_find_null()
|
||||
keyseg Array of keyparts for key suffix
|
||||
a Key suffix value tuple
|
||||
|
||||
DESCRIPTION
|
||||
Find the first NULL value in index-suffix values tuple.
|
||||
TODO Consider optimizing this fuction or its use so we don't search for
|
||||
NULL values in completely NOT NULL index suffixes.
|
||||
|
||||
RETURN
|
||||
First key part that has NULL as value in values tuple, or the last key part
|
||||
(with keyseg->type==HA_TYPE_END) if values tuple doesn't contain NULLs.
|
||||
*/
|
||||
|
||||
HA_KEYSEG *ha_find_null(HA_KEYSEG *keyseg, uchar *a)
|
||||
{
|
||||
for (; (enum ha_base_keytype) keyseg->type != HA_KEYTYPE_END; keyseg++)
|
||||
{
|
||||
uchar *end;
|
||||
if (keyseg->null_bit)
|
||||
{
|
||||
if (!*a++)
|
||||
return keyseg;
|
||||
}
|
||||
end= a+ keyseg->length;
|
||||
|
||||
switch ((enum ha_base_keytype) keyseg->type) {
|
||||
case HA_KEYTYPE_TEXT:
|
||||
case HA_KEYTYPE_BINARY:
|
||||
if (keyseg->flag & HA_SPACE_PACK)
|
||||
{
|
||||
int a_length;
|
||||
get_key_length(a_length, a);
|
||||
a += a_length;
|
||||
break;
|
||||
}
|
||||
else
|
||||
a= end;
|
||||
break;
|
||||
case HA_KEYTYPE_VARTEXT:
|
||||
case HA_KEYTYPE_VARBINARY:
|
||||
{
|
||||
int a_length;
|
||||
get_key_length(a_length, a);
|
||||
a+= a_length;
|
||||
break;
|
||||
}
|
||||
case HA_KEYTYPE_NUM:
|
||||
if (keyseg->flag & HA_SPACE_PACK)
|
||||
{
|
||||
int alength= *a++;
|
||||
end= a+alength;
|
||||
}
|
||||
a= end;
|
||||
break;
|
||||
case HA_KEYTYPE_INT8:
|
||||
case HA_KEYTYPE_SHORT_INT:
|
||||
case HA_KEYTYPE_USHORT_INT:
|
||||
case HA_KEYTYPE_LONG_INT:
|
||||
case HA_KEYTYPE_ULONG_INT:
|
||||
case HA_KEYTYPE_INT24:
|
||||
case HA_KEYTYPE_UINT24:
|
||||
#ifdef HAVE_LONG_LONG
|
||||
case HA_KEYTYPE_LONGLONG:
|
||||
case HA_KEYTYPE_ULONGLONG:
|
||||
#endif
|
||||
case HA_KEYTYPE_FLOAT:
|
||||
case HA_KEYTYPE_DOUBLE:
|
||||
a= end;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return keyseg;
|
||||
}
|
||||
|
||||
|
@ -426,6 +426,18 @@ MY_DIR *my_dir(const char *path, myf MyFlags)
|
||||
|
||||
do
|
||||
{
|
||||
#ifdef __BORLANDC__
|
||||
attrib= find.ff_attrib;
|
||||
#else
|
||||
attrib= find.attrib;
|
||||
/*
|
||||
Do not show hidden and system files which Windows sometimes create.
|
||||
Note. Because Borland's findfirst() is called with the third
|
||||
argument = 0 hidden/system files are excluded from the search.
|
||||
*/
|
||||
if (attrib & (_A_HIDDEN | _A_SYSTEM))
|
||||
continue;
|
||||
#endif
|
||||
#ifdef __BORLANDC__
|
||||
if (!(finfo.name= strdup_root(names_storage, find.ff_name)))
|
||||
goto error;
|
||||
@ -442,11 +454,10 @@ MY_DIR *my_dir(const char *path, myf MyFlags)
|
||||
bzero(finfo.mystat, sizeof(MY_STAT));
|
||||
#ifdef __BORLANDC__
|
||||
finfo.mystat->st_size=find.ff_fsize;
|
||||
mode=MY_S_IREAD; attrib=find.ff_attrib;
|
||||
#else
|
||||
finfo.mystat->st_size=find.size;
|
||||
mode=MY_S_IREAD; attrib=find.attrib;
|
||||
#endif
|
||||
mode=MY_S_IREAD;
|
||||
if (!(attrib & _A_RDONLY))
|
||||
mode|=MY_S_IWRITE;
|
||||
if (attrib & _A_SUBDIR)
|
||||
|
@ -98,6 +98,8 @@ public:
|
||||
StartTcTimer = 2509,
|
||||
StopTcTimer = 2510,
|
||||
StartPeriodicTcTimer = 2511,
|
||||
TcStartDumpIndexOpCount = 2512,
|
||||
TcDumpIndexOpCount = 2513,
|
||||
CmvmiDumpConnections = 2600,
|
||||
CmvmiDumpLongSignalMemory = 2601,
|
||||
CmvmiSetRestartOnErrorInsert = 2602,
|
||||
|
@ -4607,6 +4607,7 @@ void Dbtc::copyApi(Signal* signal)
|
||||
regTmpApiPtr->commitAckMarker = RNIL;
|
||||
regTmpApiPtr->firstTcConnect = RNIL;
|
||||
regTmpApiPtr->lastTcConnect = RNIL;
|
||||
releaseAllSeizedIndexOperations(regTmpApiPtr);
|
||||
}//Dbtc::copyApi()
|
||||
|
||||
void Dbtc::unlinkApiConnect(Signal* signal)
|
||||
@ -10134,7 +10135,7 @@ void Dbtc::releaseAbortResources(Signal* signal)
|
||||
// apiConnectptr.p->apiConnectstate = CS_CONNECTED;
|
||||
apiConnectptr.p->apiConnectstate = CS_ABORTING;
|
||||
apiConnectptr.p->abortState = AS_IDLE;
|
||||
|
||||
releaseAllSeizedIndexOperations(apiConnectptr.p);
|
||||
if(apiConnectptr.p->m_exec_flag || apiConnectptr.p->apiFailState == ZTRUE){
|
||||
jam();
|
||||
bool ok = false;
|
||||
@ -10707,6 +10708,33 @@ Dbtc::execDUMP_STATE_ORD(Signal* signal)
|
||||
signal->theData[0] = TcContinueB::ZTRANS_EVENT_REP;
|
||||
sendSignalWithDelay(cownref, GSN_CONTINUEB, signal, 5000, 1);
|
||||
}
|
||||
|
||||
if (dumpState->args[0] == DumpStateOrd::TcStartDumpIndexOpCount)
|
||||
{
|
||||
static int frequency = 1;
|
||||
if (signal->getLength() > 1)
|
||||
frequency = signal->theData[1];
|
||||
else
|
||||
if (refToBlock(signal->getSendersBlockRef()) != DBTC)
|
||||
frequency = 1;
|
||||
|
||||
if (frequency)
|
||||
{
|
||||
dumpState->args[0] = DumpStateOrd::TcDumpIndexOpCount;
|
||||
execDUMP_STATE_ORD(signal);
|
||||
dumpState->args[0] = DumpStateOrd::TcStartDumpIndexOpCount;
|
||||
|
||||
Uint32 delay = 1000 * (frequency > 25 ? 25 : frequency);
|
||||
sendSignalWithDelay(cownref, GSN_DUMP_STATE_ORD, signal, delay, 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (dumpState->args[0] == DumpStateOrd::TcDumpIndexOpCount)
|
||||
{
|
||||
infoEvent("IndexOpCount: pool: %d free: %d",
|
||||
c_theIndexOperationPool.getSize(),
|
||||
c_theIndexOperationPool.getNoOfFree());
|
||||
}
|
||||
}//Dbtc::execDUMP_STATE_ORD()
|
||||
|
||||
void Dbtc::execSET_VAR_REQ(Signal* signal)
|
||||
|
@ -172,7 +172,7 @@ void report_stats()
|
||||
log_msg("\nFailed %u/%u test(s), %.02f%% successful.\n",
|
||||
total_fail, total_test, percent);
|
||||
log_msg("\nThe .out and .err files in %s may give you some\n", result_dir);
|
||||
log_msg("hint of what when wrong.\n");
|
||||
log_msg("hint of what went wrong.\n");
|
||||
log_msg("\nIf you want to report this error, please first read the documentation\n");
|
||||
log_msg("at: http://www.mysql.com/doc/en/MySQL_test_suite.html\n");
|
||||
}
|
||||
@ -941,7 +941,7 @@ void run_test(char *test)
|
||||
// increment total
|
||||
++total_test;
|
||||
}
|
||||
else if (err == 2)
|
||||
else if (err == 62) // To reflect the changes made in client/mysqltest.c
|
||||
{
|
||||
// skip
|
||||
rstr = TEST_SKIP;
|
||||
|
@ -40,7 +40,7 @@ TYPELIB myisam_recover_typelib= {array_elements(myisam_recover_names)-1,"",
|
||||
myisam_recover_names, NULL};
|
||||
|
||||
const char *myisam_stats_method_names[] = {"nulls_unequal", "nulls_equal",
|
||||
NullS};
|
||||
"nulls_ignored", NullS};
|
||||
TYPELIB myisam_stats_method_typelib= {
|
||||
array_elements(myisam_stats_method_names) - 1, "",
|
||||
myisam_stats_method_names, NULL};
|
||||
|
@ -1768,7 +1768,7 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
|
||||
Item** res= find_item_in_list(this, thd->lex->current_select->item_list,
|
||||
&counter, REPORT_EXCEPT_NOT_FOUND,
|
||||
¬_used);
|
||||
if (res != not_found_item && (*res)->type() == Item::FIELD_ITEM)
|
||||
if (res != (Item **)not_found_item && (*res)->type() == Item::FIELD_ITEM)
|
||||
{
|
||||
set_field((*((Item_field**)res))->field);
|
||||
return 0;
|
||||
@ -2796,8 +2796,14 @@ bool Item_insert_value::fix_fields(THD *thd,
|
||||
Item **items)
|
||||
{
|
||||
DBUG_ASSERT(fixed == 0);
|
||||
st_table_list *orig_next_table= table_list->next;
|
||||
table_list->next= 0;
|
||||
if (!arg->fixed && arg->fix_fields(thd, table_list, &arg))
|
||||
{
|
||||
table_list->next= orig_next_table;
|
||||
return 1;
|
||||
}
|
||||
table_list->next= orig_next_table;
|
||||
|
||||
if (arg->type() == REF_ITEM)
|
||||
{
|
||||
@ -2809,6 +2815,7 @@ bool Item_insert_value::fix_fields(THD *thd,
|
||||
arg= ref->ref[0];
|
||||
}
|
||||
Item_field *field_arg= (Item_field *)arg;
|
||||
|
||||
if (field_arg->field->table->insert_values)
|
||||
{
|
||||
Field *def_field= (Field*) sql_alloc(field_arg->field->size_of());
|
||||
|
@ -3253,7 +3253,6 @@ Item *get_system_var(THD *thd, enum_var_type var_type, LEX_STRING name,
|
||||
LEX_STRING component)
|
||||
{
|
||||
sys_var *var;
|
||||
char buff[MAX_SYS_VAR_LENGTH*2+4+8], *pos;
|
||||
LEX_STRING *base_name, *component_name;
|
||||
|
||||
if (component.str == 0 &&
|
||||
|
@ -444,12 +444,15 @@ public:
|
||||
class Item_func_char :public Item_str_func
|
||||
{
|
||||
public:
|
||||
Item_func_char(List<Item> &list) :Item_str_func(list) {}
|
||||
Item_func_char(List<Item> &list) :Item_str_func(list)
|
||||
{ collation.set(default_charset()); }
|
||||
Item_func_char(List<Item> &list, CHARSET_INFO *cs) :Item_str_func(list)
|
||||
{ collation.set(cs); }
|
||||
String *val_str(String *);
|
||||
void fix_length_and_dec()
|
||||
{
|
||||
collation.set(default_charset());
|
||||
maybe_null=0; max_length=arg_count;
|
||||
maybe_null=0;
|
||||
max_length=arg_count * collation.collation->mbmaxlen;
|
||||
}
|
||||
const char *func_name() const { return "char"; }
|
||||
};
|
||||
|
@ -1528,6 +1528,16 @@ void Item_func_date_format::fix_length_and_dec()
|
||||
if (args[1]->type() == STRING_ITEM)
|
||||
{ // Optimize the normal case
|
||||
fixed_length=1;
|
||||
|
||||
/*
|
||||
Force case sensitive collation on format string.
|
||||
This needed because format modifiers with different case,
|
||||
for example %m and %M, have different meaning. Thus eq()
|
||||
will distinguish them.
|
||||
*/
|
||||
args[1]->collation.set(
|
||||
get_charset_by_csname(args[1]->collation.collation->csname,
|
||||
MY_CS_BINSORT,MYF(0)), DERIVATION_COERCIBLE);
|
||||
/*
|
||||
The result is a binary string (no reason to use collation->mbmaxlen
|
||||
This is becasue make_date_time() only returns binary strings
|
||||
|
@ -1105,6 +1105,8 @@ void change_byte(byte *,uint,char,char);
|
||||
void init_read_record(READ_RECORD *info, THD *thd, TABLE *reg_form,
|
||||
SQL_SELECT *select,
|
||||
int use_record_cache, bool print_errors);
|
||||
void init_read_record_idx(READ_RECORD *info, THD *thd, TABLE *table,
|
||||
bool print_error, uint idx);
|
||||
void end_read_record(READ_RECORD *info);
|
||||
ha_rows filesort(THD *thd, TABLE *form,struct st_sort_field *sortorder,
|
||||
uint s_length, SQL_SELECT *select,
|
||||
|
@ -5281,7 +5281,8 @@ The minimum value for this variable is 4096.",
|
||||
GET_ULONG, REQUIRED_ARG, 8192*1024, 4, ~0L, 0, 1, 0},
|
||||
{"myisam_stats_method", OPT_MYISAM_STATS_METHOD,
|
||||
"Specifies how MyISAM index statistics collection code should threat NULLs. "
|
||||
"Possible values of name are \"nulls_unequal\" (default behavior for 4.1/5.0), and \"nulls_equal\" (emulate 4.0 behavior).",
|
||||
"Possible values of name are \"nulls_unequal\" (default behavior for 4.1/5.0), "
|
||||
"\"nulls_equal\" (emulate 4.0 behavior), and \"nulls_ignored\".",
|
||||
(gptr*) &myisam_stats_method_str, (gptr*) &myisam_stats_method_str, 0,
|
||||
GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
|
||||
{"net_buffer_length", OPT_NET_BUFFER_LENGTH,
|
||||
@ -5349,7 +5350,8 @@ The minimum value for this variable is 4096.",
|
||||
"Persistent buffer for query parsing and execution",
|
||||
(gptr*) &global_system_variables.query_prealloc_size,
|
||||
(gptr*) &max_system_variables.query_prealloc_size, 0, GET_ULONG,
|
||||
REQUIRED_ARG, QUERY_ALLOC_PREALLOC_SIZE, 16384, ~0L, 0, 1024, 0},
|
||||
REQUIRED_ARG, QUERY_ALLOC_PREALLOC_SIZE, QUERY_ALLOC_PREALLOC_SIZE,
|
||||
~0L, 0, 1024, 0},
|
||||
{"range_alloc_block_size", OPT_RANGE_ALLOC_BLOCK_SIZE,
|
||||
"Allocation block size for storing ranges during optimization",
|
||||
(gptr*) &global_system_variables.range_alloc_block_size,
|
||||
@ -6474,16 +6476,26 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
|
||||
}
|
||||
case OPT_MYISAM_STATS_METHOD:
|
||||
{
|
||||
myisam_stats_method_str= argument;
|
||||
int method;
|
||||
ulong method_conv;
|
||||
myisam_stats_method_str= argument;
|
||||
if ((method=find_type(argument, &myisam_stats_method_typelib, 2)) <= 0)
|
||||
{
|
||||
fprintf(stderr, "Invalid value of myisam_stats_method: %s.\n", argument);
|
||||
exit(1);
|
||||
}
|
||||
global_system_variables.myisam_stats_method=
|
||||
test(method-1)? MI_STATS_METHOD_NULLS_EQUAL :
|
||||
MI_STATS_METHOD_NULLS_NOT_EQUAL;
|
||||
switch (method-1) {
|
||||
case 0:
|
||||
method_conv= MI_STATS_METHOD_NULLS_EQUAL;
|
||||
break;
|
||||
case 1:
|
||||
method_conv= MI_STATS_METHOD_NULLS_NOT_EQUAL;
|
||||
break;
|
||||
case 2:
|
||||
method_conv= MI_STATS_METHOD_IGNORE_NULLS;
|
||||
break;
|
||||
}
|
||||
global_system_variables.myisam_stats_method= method_conv;
|
||||
break;
|
||||
}
|
||||
case OPT_SQL_MODE:
|
||||
|
@ -582,6 +582,96 @@ SEL_ARG *SEL_ARG::clone_tree()
|
||||
return root;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Find the best index to retrieve first N records in given order
|
||||
|
||||
SYNOPSIS
|
||||
get_index_for_order()
|
||||
table Table to be accessed
|
||||
order Required ordering
|
||||
limit Number of records that will be retrieved
|
||||
|
||||
DESCRIPTION
|
||||
Find the best index that allows to retrieve first #limit records in the
|
||||
given order cheaper then one would retrieve them using full table scan.
|
||||
|
||||
IMPLEMENTATION
|
||||
Run through all table indexes and find the shortest index that allows
|
||||
records to be retrieved in given order. We look for the shortest index
|
||||
as we will have fewer index pages to read with it.
|
||||
|
||||
This function is used only by UPDATE/DELETE, so we take into account how
|
||||
the UPDATE/DELETE code will work:
|
||||
* index can only be scanned in forward direction
|
||||
* HA_EXTRA_KEYREAD will not be used
|
||||
Perhaps these assumptions could be relaxed
|
||||
|
||||
RETURN
|
||||
index number
|
||||
MAX_KEY if no such index was found.
|
||||
*/
|
||||
|
||||
uint get_index_for_order(TABLE *table, ORDER *order, ha_rows limit)
|
||||
{
|
||||
uint idx;
|
||||
uint match_key= MAX_KEY, match_key_len= MAX_KEY_LENGTH + 1;
|
||||
ORDER *ord;
|
||||
|
||||
for (ord= order; ord; ord= ord->next)
|
||||
if (!ord->asc)
|
||||
return MAX_KEY;
|
||||
|
||||
for (idx= 0; idx < table->keys; idx++)
|
||||
{
|
||||
if (!(table->keys_in_use_for_query.is_set(idx)))
|
||||
continue;
|
||||
KEY_PART_INFO *keyinfo= table->key_info[idx].key_part;
|
||||
uint partno= 0;
|
||||
|
||||
/*
|
||||
The below check is sufficient considering we now have either BTREE
|
||||
indexes (records are returned in order for any index prefix) or HASH
|
||||
indexes (records are not returned in order for any index prefix).
|
||||
*/
|
||||
if (!(table->file->index_flags(idx, 0, 1) & HA_READ_ORDER))
|
||||
continue;
|
||||
for (ord= order; ord; ord= ord->next, partno++)
|
||||
{
|
||||
Item *item= order->item[0];
|
||||
if (!(item->type() == Item::FIELD_ITEM &&
|
||||
((Item_field*)item)->field->eq(keyinfo[partno].field)))
|
||||
break;
|
||||
}
|
||||
|
||||
if (!ord && table->key_info[idx].key_length < match_key_len)
|
||||
{
|
||||
/*
|
||||
Ok, the ordering is compatible and this key is shorter then
|
||||
previous match (we want shorter keys as we'll have to read fewer
|
||||
index pages for the same number of records)
|
||||
*/
|
||||
match_key= idx;
|
||||
match_key_len= table->key_info[idx].key_length;
|
||||
}
|
||||
}
|
||||
|
||||
if (match_key != MAX_KEY)
|
||||
{
|
||||
/*
|
||||
Found an index that allows records to be retrieved in the requested
|
||||
order. Now we'll check if using the index is cheaper then doing a table
|
||||
scan.
|
||||
*/
|
||||
double full_scan_time= table->file->scan_time();
|
||||
double index_scan_time= table->file->read_time(match_key, 1, limit);
|
||||
if (index_scan_time > full_scan_time)
|
||||
match_key= MAX_KEY;
|
||||
}
|
||||
return match_key;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Test if a key can be used in different ranges
|
||||
|
||||
|
@ -167,4 +167,6 @@ public:
|
||||
QUICK_SELECT *get_quick_select_for_ref(THD *thd, TABLE *table,
|
||||
struct st_table_ref *ref);
|
||||
|
||||
uint get_index_for_order(TABLE *table, ORDER *order, ha_rows limit);
|
||||
|
||||
#endif
|
||||
|
196
sql/records.cc
196
sql/records.cc
@ -28,8 +28,52 @@ static int rr_from_pointers(READ_RECORD *info);
|
||||
static int rr_from_cache(READ_RECORD *info);
|
||||
static int init_rr_cache(READ_RECORD *info);
|
||||
static int rr_cmp(uchar *a,uchar *b);
|
||||
static int rr_index_first(READ_RECORD *info);
|
||||
static int rr_index(READ_RECORD *info);
|
||||
|
||||
/* init struct for read with info->read_record */
|
||||
|
||||
/*
|
||||
Initialize READ_RECORD structure to perform full index scan
|
||||
|
||||
SYNOPSIS
|
||||
init_read_record_idx()
|
||||
info READ_RECORD structure to initialize.
|
||||
thd Thread handle
|
||||
table Table to be accessed
|
||||
print_error If true, call table->file->print_error() if an error
|
||||
occurs (except for end-of-records error)
|
||||
idx index to scan
|
||||
|
||||
DESCRIPTION
|
||||
Initialize READ_RECORD structure to perform full index scan (in forward
|
||||
direction) using read_record.read_record() interface.
|
||||
|
||||
This function has been added at late stage and is used only by
|
||||
UPDATE/DELETE. Other statements perform index scans using
|
||||
join_read_first/next functions.
|
||||
*/
|
||||
|
||||
void init_read_record_idx(READ_RECORD *info, THD *thd, TABLE *table,
|
||||
bool print_error, uint idx)
|
||||
{
|
||||
bzero((char*) info,sizeof(*info));
|
||||
info->table= table;
|
||||
info->file= table->file;
|
||||
info->record= table->record[0];
|
||||
info->print_error= print_error;
|
||||
|
||||
table->status=0; /* And it's always found */
|
||||
if (!table->file->inited)
|
||||
{
|
||||
table->file->ha_index_init(idx);
|
||||
table->file->extra(HA_EXTRA_RETRIEVE_PRIMARY_KEY);
|
||||
}
|
||||
/* read_record will be changed to rr_index in rr_index_first */
|
||||
info->read_record= rr_index_first;
|
||||
}
|
||||
|
||||
|
||||
/* init struct for read with info->read_record */
|
||||
|
||||
void init_read_record(READ_RECORD *info,THD *thd, TABLE *table,
|
||||
SQL_SELECT *select,
|
||||
@ -152,6 +196,21 @@ void end_read_record(READ_RECORD *info)
|
||||
}
|
||||
}
|
||||
|
||||
static int rr_handle_error(READ_RECORD *info, int error)
|
||||
{
|
||||
if (error == HA_ERR_END_OF_FILE)
|
||||
error= -1;
|
||||
else
|
||||
{
|
||||
if (info->print_error)
|
||||
info->table->file->print_error(error, MYF(0));
|
||||
if (error < 0) // Fix negative BDB errno
|
||||
error= 1;
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/* Read a record from head-database */
|
||||
|
||||
static int rr_quick(READ_RECORD *info)
|
||||
@ -166,15 +225,7 @@ static int rr_quick(READ_RECORD *info)
|
||||
}
|
||||
if (tmp != HA_ERR_RECORD_DELETED)
|
||||
{
|
||||
if (tmp == HA_ERR_END_OF_FILE)
|
||||
tmp= -1;
|
||||
else
|
||||
{
|
||||
if (info->print_error)
|
||||
info->file->print_error(tmp,MYF(0));
|
||||
if (tmp < 0) // Fix negative BDB errno
|
||||
tmp=1;
|
||||
}
|
||||
tmp= rr_handle_error(info, tmp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -182,6 +233,57 @@ static int rr_quick(READ_RECORD *info)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Reads first row in an index scan
|
||||
|
||||
SYNOPSIS
|
||||
rr_index_first()
|
||||
info Scan info
|
||||
|
||||
RETURN
|
||||
0 Ok
|
||||
-1 End of records
|
||||
1 Error
|
||||
*/
|
||||
|
||||
|
||||
static int rr_index_first(READ_RECORD *info)
|
||||
{
|
||||
int tmp= info->file->index_first(info->record);
|
||||
info->read_record= rr_index;
|
||||
if (tmp)
|
||||
tmp= rr_handle_error(info, tmp);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Reads index sequentially after first row
|
||||
|
||||
SYNOPSIS
|
||||
rr_index()
|
||||
info Scan info
|
||||
|
||||
DESCRIPTION
|
||||
Read the next index record (in forward direction) and translate return
|
||||
value.
|
||||
|
||||
RETURN
|
||||
0 Ok
|
||||
-1 End of records
|
||||
1 Error
|
||||
*/
|
||||
|
||||
|
||||
static int rr_index(READ_RECORD *info)
|
||||
{
|
||||
int tmp= info->file->index_next(info->record);
|
||||
if (tmp)
|
||||
tmp= rr_handle_error(info, tmp);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
|
||||
static int rr_sequential(READ_RECORD *info)
|
||||
{
|
||||
int tmp;
|
||||
@ -192,17 +294,13 @@ static int rr_sequential(READ_RECORD *info)
|
||||
my_error(ER_SERVER_SHUTDOWN,MYF(0));
|
||||
return 1;
|
||||
}
|
||||
/*
|
||||
rnd_next can return RECORD_DELETED for MyISAM when one thread is
|
||||
reading and another deleting without locks.
|
||||
*/
|
||||
if (tmp != HA_ERR_RECORD_DELETED)
|
||||
{
|
||||
if (tmp == HA_ERR_END_OF_FILE)
|
||||
tmp= -1;
|
||||
else
|
||||
{
|
||||
if (info->print_error)
|
||||
info->table->file->print_error(tmp,MYF(0));
|
||||
if (tmp < 0) // Fix negative BDB errno
|
||||
tmp=1;
|
||||
}
|
||||
tmp= rr_handle_error(info, tmp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -213,23 +311,18 @@ static int rr_sequential(READ_RECORD *info)
|
||||
static int rr_from_tempfile(READ_RECORD *info)
|
||||
{
|
||||
int tmp;
|
||||
tryNext:
|
||||
if (my_b_read(info->io_cache,info->ref_pos,info->ref_length))
|
||||
return -1; /* End of file */
|
||||
if ((tmp=info->file->rnd_pos(info->record,info->ref_pos)))
|
||||
for (;;)
|
||||
{
|
||||
if (tmp == HA_ERR_END_OF_FILE)
|
||||
tmp= -1;
|
||||
else if (tmp == HA_ERR_RECORD_DELETED ||
|
||||
(tmp == HA_ERR_KEY_NOT_FOUND && info->ignore_not_found_rows))
|
||||
goto tryNext;
|
||||
else
|
||||
{
|
||||
if (info->print_error)
|
||||
info->file->print_error(tmp,MYF(0));
|
||||
if (tmp < 0) // Fix negative BDB errno
|
||||
tmp=1;
|
||||
}
|
||||
if (my_b_read(info->io_cache,info->ref_pos,info->ref_length))
|
||||
return -1; /* End of file */
|
||||
if (!(tmp=info->file->rnd_pos(info->record,info->ref_pos)))
|
||||
break;
|
||||
/* The following is extremely unlikely to happen */
|
||||
if (tmp == HA_ERR_RECORD_DELETED ||
|
||||
(tmp == HA_ERR_KEY_NOT_FOUND && info->ignore_not_found_rows))
|
||||
continue;
|
||||
tmp= rr_handle_error(info, tmp);
|
||||
break;
|
||||
}
|
||||
return tmp;
|
||||
} /* rr_from_tempfile */
|
||||
@ -267,26 +360,23 @@ static int rr_from_pointers(READ_RECORD *info)
|
||||
{
|
||||
int tmp;
|
||||
byte *cache_pos;
|
||||
tryNext:
|
||||
if (info->cache_pos == info->cache_end)
|
||||
return -1; /* End of file */
|
||||
cache_pos=info->cache_pos;
|
||||
info->cache_pos+=info->ref_length;
|
||||
|
||||
if ((tmp=info->file->rnd_pos(info->record,cache_pos)))
|
||||
for (;;)
|
||||
{
|
||||
if (tmp == HA_ERR_END_OF_FILE)
|
||||
tmp= -1;
|
||||
else if (tmp == HA_ERR_RECORD_DELETED ||
|
||||
(tmp == HA_ERR_KEY_NOT_FOUND && info->ignore_not_found_rows))
|
||||
goto tryNext;
|
||||
else
|
||||
{
|
||||
if (info->print_error)
|
||||
info->file->print_error(tmp,MYF(0));
|
||||
if (tmp < 0) // Fix negative BDB errno
|
||||
tmp=1;
|
||||
}
|
||||
if (info->cache_pos == info->cache_end)
|
||||
return -1; /* End of file */
|
||||
cache_pos= info->cache_pos;
|
||||
info->cache_pos+= info->ref_length;
|
||||
|
||||
if (!(tmp=info->file->rnd_pos(info->record,cache_pos)))
|
||||
break;
|
||||
|
||||
/* The following is extremely unlikely to happen */
|
||||
if (tmp == HA_ERR_RECORD_DELETED ||
|
||||
(tmp == HA_ERR_KEY_NOT_FOUND && info->ignore_not_found_rows))
|
||||
continue;
|
||||
tmp= rr_handle_error(info, tmp);
|
||||
break;
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
|
@ -193,6 +193,7 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables)
|
||||
my_bool return_val= 1;
|
||||
bool check_no_resolve= specialflag & SPECIAL_NO_RESOLVE;
|
||||
char tmp_name[NAME_LEN+1];
|
||||
int password_length;
|
||||
DBUG_ENTER("acl_load");
|
||||
|
||||
priv_version++; /* Privileges updated */
|
||||
@ -250,7 +251,9 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables)
|
||||
|
||||
init_read_record(&read_record_info,thd,table=tables[1].table,NULL,1,0);
|
||||
VOID(my_init_dynamic_array(&acl_users,sizeof(ACL_USER),50,100));
|
||||
if (table->field[2]->field_length < SCRAMBLED_PASSWORD_CHAR_LENGTH_323)
|
||||
password_length= table->field[2]->field_length /
|
||||
table->field[2]->charset()->mbmaxlen;
|
||||
if (password_length < SCRAMBLED_PASSWORD_CHAR_LENGTH_323)
|
||||
{
|
||||
sql_print_error("Fatal error: mysql.user table is damaged or in "
|
||||
"unsupported 3.20 format.");
|
||||
@ -258,10 +261,10 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables)
|
||||
}
|
||||
|
||||
DBUG_PRINT("info",("user table fields: %d, password length: %d",
|
||||
table->fields, table->field[2]->field_length));
|
||||
table->fields, password_length));
|
||||
|
||||
pthread_mutex_lock(&LOCK_global_system_variables);
|
||||
if (table->field[2]->field_length < SCRAMBLED_PASSWORD_CHAR_LENGTH)
|
||||
if (password_length < SCRAMBLED_PASSWORD_CHAR_LENGTH)
|
||||
{
|
||||
if (opt_secure_auth)
|
||||
{
|
||||
|
@ -37,6 +37,7 @@ int mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
|
||||
bool using_limit=limit != HA_POS_ERROR;
|
||||
bool transactional_table, log_delayed, safe_update, const_cond;
|
||||
ha_rows deleted;
|
||||
uint usable_index= MAX_KEY;
|
||||
DBUG_ENTER("mysql_delete");
|
||||
|
||||
if ((open_and_lock_tables(thd, table_list)))
|
||||
@ -119,30 +120,47 @@ int mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
|
||||
tables.table = table;
|
||||
tables.alias = table_list->alias;
|
||||
|
||||
table->sort.io_cache = (IO_CACHE *) my_malloc(sizeof(IO_CACHE),
|
||||
MYF(MY_FAE | MY_ZEROFILL));
|
||||
if (thd->lex->select_lex.setup_ref_array(thd, order->elements) ||
|
||||
setup_order(thd, thd->lex->select_lex.ref_pointer_array, &tables,
|
||||
fields, all_fields, (ORDER*) order->first) ||
|
||||
!(sortorder=make_unireg_sortorder((ORDER*) order->first, &length)) ||
|
||||
(table->sort.found_records = filesort(thd, table, sortorder, length,
|
||||
select, HA_POS_ERROR,
|
||||
&examined_rows))
|
||||
== HA_POS_ERROR)
|
||||
fields, all_fields, (ORDER*) order->first))
|
||||
{
|
||||
delete select;
|
||||
free_underlaid_joins(thd, &thd->lex->select_lex);
|
||||
DBUG_RETURN(-1); // This will force out message
|
||||
}
|
||||
/*
|
||||
Filesort has already found and selected the rows we want to delete,
|
||||
so we don't need the where clause
|
||||
*/
|
||||
delete select;
|
||||
select= 0;
|
||||
|
||||
if (!select && limit != HA_POS_ERROR)
|
||||
usable_index= get_index_for_order(table, (ORDER*)(order->first), limit);
|
||||
|
||||
if (usable_index == MAX_KEY)
|
||||
{
|
||||
table->sort.io_cache= (IO_CACHE *) my_malloc(sizeof(IO_CACHE),
|
||||
MYF(MY_FAE | MY_ZEROFILL));
|
||||
|
||||
if ( !(sortorder=make_unireg_sortorder((ORDER*) order->first, &length)) ||
|
||||
(table->sort.found_records = filesort(thd, table, sortorder, length,
|
||||
select, HA_POS_ERROR,
|
||||
&examined_rows))
|
||||
== HA_POS_ERROR)
|
||||
{
|
||||
delete select;
|
||||
free_underlaid_joins(thd, &thd->lex->select_lex);
|
||||
DBUG_RETURN(-1); // This will force out message
|
||||
}
|
||||
/*
|
||||
Filesort has already found and selected the rows we want to delete,
|
||||
so we don't need the where clause
|
||||
*/
|
||||
delete select;
|
||||
select= 0;
|
||||
}
|
||||
}
|
||||
|
||||
init_read_record(&info,thd,table,select,1,1);
|
||||
if (usable_index==MAX_KEY)
|
||||
init_read_record(&info,thd,table,select,1,1);
|
||||
else
|
||||
init_read_record_idx(&info, thd, table, 1, usable_index);
|
||||
|
||||
deleted=0L;
|
||||
init_ftfuncs(thd, &thd->lex->select_lex, 1);
|
||||
thd->proc_info="updating";
|
||||
|
@ -806,8 +806,20 @@ int READ_INFO::read_field()
|
||||
*to++= (byte) escape_char;
|
||||
goto found_eof;
|
||||
}
|
||||
*to++ = (byte) unescape((char) chr);
|
||||
continue;
|
||||
/*
|
||||
When escape_char == enclosed_char, we treat it like we do for
|
||||
handling quotes in SQL parsing -- you can double-up the
|
||||
escape_char to include it literally, but it doesn't do escapes
|
||||
like \n. This allows: LOAD DATA ... ENCLOSED BY '"' ESCAPED BY '"'
|
||||
with data like: "fie""ld1", "field2"
|
||||
*/
|
||||
if (escape_char != enclosed_char || chr == escape_char)
|
||||
{
|
||||
*to++ = (byte) unescape((char) chr);
|
||||
continue;
|
||||
}
|
||||
PUSH(chr);
|
||||
chr= escape_char;
|
||||
}
|
||||
#ifdef ALLOW_LINESEPARATOR_IN_STRINGS
|
||||
if (chr == line_term_char)
|
||||
|
@ -689,6 +689,7 @@ JOIN::optimize()
|
||||
{
|
||||
order=0; // The output has only one row
|
||||
simple_order=1;
|
||||
select_distinct= 0; // No need in distinct for 1 row
|
||||
}
|
||||
|
||||
calc_group_buffer(this, group_list);
|
||||
|
@ -61,7 +61,8 @@ int mysql_update(THD *thd,
|
||||
bool safe_update= thd->options & OPTION_SAFE_UPDATES;
|
||||
bool used_key_is_modified, transactional_table, log_delayed;
|
||||
int error=0;
|
||||
uint used_index;
|
||||
uint used_index= MAX_KEY;
|
||||
bool need_sort= TRUE;
|
||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||
uint want_privilege;
|
||||
#endif
|
||||
@ -145,6 +146,11 @@ int mysql_update(THD *thd,
|
||||
send_ok(thd); // No matching records
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
if (!select && limit != HA_POS_ERROR)
|
||||
{
|
||||
if ((used_index= get_index_for_order(table, order, limit)) != MAX_KEY)
|
||||
need_sort= FALSE;
|
||||
}
|
||||
/* If running in safe sql mode, don't allow updates without keys */
|
||||
if (table->quick_keys.is_clear_all())
|
||||
{
|
||||
@ -157,6 +163,7 @@ int mysql_update(THD *thd,
|
||||
}
|
||||
}
|
||||
init_ftfuncs(thd, &thd->lex->select_lex, 1);
|
||||
|
||||
/* Check if we are modifying a key that we are used to search with */
|
||||
if (select && select->quick)
|
||||
{
|
||||
@ -164,13 +171,15 @@ int mysql_update(THD *thd,
|
||||
used_key_is_modified= (!select->quick->unique_key_range() &&
|
||||
check_if_key_used(table, used_index, fields));
|
||||
}
|
||||
else if ((used_index=table->file->key_used_on_scan) < MAX_KEY)
|
||||
used_key_is_modified=check_if_key_used(table, used_index, fields);
|
||||
else
|
||||
{
|
||||
used_key_is_modified=0;
|
||||
used_index= MAX_KEY;
|
||||
used_key_is_modified= 0;
|
||||
if (used_index == MAX_KEY) // no index for sort order
|
||||
used_index= table->file->key_used_on_scan;
|
||||
if (used_index != MAX_KEY)
|
||||
used_key_is_modified= check_if_key_used(table, used_index, fields);
|
||||
}
|
||||
|
||||
if (used_key_is_modified || order)
|
||||
{
|
||||
/*
|
||||
@ -184,7 +193,8 @@ int mysql_update(THD *thd,
|
||||
table->file->extra(HA_EXTRA_KEYREAD);
|
||||
}
|
||||
|
||||
if (order)
|
||||
/* note: can actually avoid sorting below.. */
|
||||
if (order && (need_sort || used_key_is_modified))
|
||||
{
|
||||
/*
|
||||
Doing an ORDER BY; Let filesort find and sort the rows we are going
|
||||
@ -194,6 +204,7 @@ int mysql_update(THD *thd,
|
||||
SORT_FIELD *sortorder;
|
||||
ha_rows examined_rows;
|
||||
|
||||
used_index= MAX_KEY; // For call to init_read_record()
|
||||
table->sort.io_cache = (IO_CACHE *) my_malloc(sizeof(IO_CACHE),
|
||||
MYF(MY_FAE | MY_ZEROFILL));
|
||||
if (!(sortorder=make_unireg_sortorder(order, &length)) ||
|
||||
@ -225,7 +236,11 @@ int mysql_update(THD *thd,
|
||||
DISK_BUFFER_SIZE, MYF(MY_WME)))
|
||||
goto err;
|
||||
|
||||
init_read_record(&info,thd,table,select,0,1);
|
||||
if (used_index == MAX_KEY)
|
||||
init_read_record(&info,thd,table,select,0,1);
|
||||
else
|
||||
init_read_record_idx(&info, thd, table, 1, used_index);
|
||||
|
||||
thd->proc_info="Searching rows for update";
|
||||
uint tmp_limit= limit;
|
||||
|
||||
@ -251,6 +266,7 @@ int mysql_update(THD *thd,
|
||||
error= 1; // Aborted
|
||||
limit= tmp_limit;
|
||||
end_read_record(&info);
|
||||
|
||||
/* Change select to use tempfile */
|
||||
if (select)
|
||||
{
|
||||
|
@ -2924,6 +2924,8 @@ simple_expr:
|
||||
{ $$= new Item_func_atan($3,$5); }
|
||||
| CHAR_SYM '(' expr_list ')'
|
||||
{ $$= new Item_func_char(*$3); }
|
||||
| CHAR_SYM '(' expr_list USING charset_name ')'
|
||||
{ $$= new Item_func_char(*$3, $5); }
|
||||
| CHARSET '(' expr ')'
|
||||
{ $$= new Item_func_charset($3); }
|
||||
| COALESCE '(' expr_list ')'
|
||||
|
@ -169,50 +169,68 @@ static int my_read_charset_file(const char *filename)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static int
|
||||
is_case_sensitive(CHARSET_INFO *cs)
|
||||
{
|
||||
return (cs->sort_order &&
|
||||
cs->sort_order['A'] < cs->sort_order['a'] &&
|
||||
cs->sort_order['a'] < cs->sort_order['B']) ? 1 : 0;
|
||||
}
|
||||
|
||||
void dispcset(FILE *f,CHARSET_INFO *cs)
|
||||
{
|
||||
fprintf(f,"{\n");
|
||||
fprintf(f," %d,%d,%d,\n",cs->number,0,0);
|
||||
fprintf(f," MY_CS_COMPILED%s%s,\n",
|
||||
fprintf(f," MY_CS_COMPILED%s%s%s,\n",
|
||||
cs->state & MY_CS_BINSORT ? "|MY_CS_BINSORT" : "",
|
||||
cs->state & MY_CS_PRIMARY ? "|MY_CS_PRIMARY" : "");
|
||||
cs->state & MY_CS_PRIMARY ? "|MY_CS_PRIMARY" : "",
|
||||
is_case_sensitive(cs) ? "|MY_CS_CSSORT" : "");
|
||||
|
||||
if (cs->name)
|
||||
{
|
||||
fprintf(f," \"%s\",\n",cs->csname);
|
||||
fprintf(f," \"%s\",\n",cs->name);
|
||||
fprintf(f," \"\",\n");
|
||||
fprintf(f," ctype_%s,\n",cs->name);
|
||||
fprintf(f," to_lower_%s,\n",cs->name);
|
||||
fprintf(f," to_upper_%s,\n",cs->name);
|
||||
fprintf(f," \"%s\", /* cset name */\n",cs->csname);
|
||||
fprintf(f," \"%s\", /* coll name */\n",cs->name);
|
||||
fprintf(f," \"\", /* comment */\n");
|
||||
fprintf(f," NULL, /* tailoring */\n");
|
||||
fprintf(f," ctype_%s, /* ctype */\n",cs->name);
|
||||
fprintf(f," to_lower_%s, /* lower */\n",cs->name);
|
||||
fprintf(f," to_upper_%s, /* upper */\n",cs->name);
|
||||
if (cs->sort_order)
|
||||
fprintf(f," sort_order_%s,\n",cs->name);
|
||||
fprintf(f," sort_order_%s, /* sort_order */\n",cs->name);
|
||||
else
|
||||
fprintf(f," NULL,\n");
|
||||
fprintf(f," to_uni_%s,\n",cs->name);
|
||||
fprintf(f," from_uni_%s,\n",cs->name);
|
||||
fprintf(f," NULL, /* sort_order */\n");
|
||||
fprintf(f," NULL, /* contractions */\n");
|
||||
fprintf(f," NULL, /* sort_order_big*/\n");
|
||||
fprintf(f," to_uni_%s, /* to_uni */\n",cs->name);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(f," NULL,\n");
|
||||
fprintf(f," NULL,\n");
|
||||
fprintf(f," NULL,\n");
|
||||
fprintf(f," NULL,\n");
|
||||
fprintf(f," NULL,\n");
|
||||
fprintf(f," NULL,\n");
|
||||
fprintf(f," NULL,\n");
|
||||
fprintf(f," NULL,\n");
|
||||
fprintf(f," NULL,\n");
|
||||
fprintf(f," NULL, /* cset name */\n");
|
||||
fprintf(f," NULL, /* coll name */\n");
|
||||
fprintf(f," NULL, /* comment */\n");
|
||||
fprintf(f," NULL, /* tailoging */\n");
|
||||
fprintf(f," NULL, /* ctype */\n");
|
||||
fprintf(f," NULL, /* lower */\n");
|
||||
fprintf(f," NULL, /* upper */\n");
|
||||
fprintf(f," NULL, /* sort order */\n");
|
||||
fprintf(f," NULL, /* contractions */\n");
|
||||
fprintf(f," NULL, /* sort_order_big*/\n");
|
||||
fprintf(f," NULL, /* to_uni */\n");
|
||||
}
|
||||
|
||||
fprintf(f," \"\",\n");
|
||||
fprintf(f," \"\",\n");
|
||||
fprintf(f," 0,\n");
|
||||
fprintf(f," 0,\n");
|
||||
fprintf(f," 0,\n");
|
||||
|
||||
fprintf(f," NULL, /* from_uni */\n");
|
||||
fprintf(f," NULL, /* state map */\n");
|
||||
fprintf(f," NULL, /* ident map */\n");
|
||||
fprintf(f," 1, /* strxfrm_multiply*/\n");
|
||||
fprintf(f," 1, /* mbminlen */\n");
|
||||
fprintf(f," 1, /* mbmaxlen */\n");
|
||||
fprintf(f," 0, /* min_sort_char */\n");
|
||||
fprintf(f," 255, /* max_sort_char */\n");
|
||||
fprintf(f," 0, /* escape_with_backslash_is_dangerous */\n");
|
||||
|
||||
fprintf(f," &my_charset_8bit_handler,\n");
|
||||
if (cs->state & MY_CS_BINSORT)
|
||||
fprintf(f," &my_collation_bin_handler,\n");
|
||||
fprintf(f," &my_collation_8bit_bin_handler,\n");
|
||||
else
|
||||
fprintf(f," &my_collation_8bit_simple_ci_handler,\n");
|
||||
fprintf(f,"}\n");
|
||||
@ -251,6 +269,11 @@ main(int argc, char **argv __attribute__((unused)))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fprintf(f,"#include <my_global.h>\n");
|
||||
fprintf(f,"#include <m_ctype.h>\n\n");
|
||||
|
||||
|
||||
for (cs=all_charsets; cs < all_charsets+256; cs++)
|
||||
{
|
||||
if (simple_cs_is_full(cs))
|
||||
|
@ -867,7 +867,7 @@ int my_longlong10_to_str_8bit(CHARSET_INFO *cs __attribute__((unused)),
|
||||
while (long_val != 0)
|
||||
{
|
||||
long quo= long_val/10;
|
||||
*--p = '0' + (long_val - quo*10);
|
||||
*--p = (char) ('0' + (long_val - quo*10));
|
||||
long_val= quo;
|
||||
}
|
||||
|
||||
|
@ -1043,7 +1043,7 @@ int my_ll10tostr_ucs2(CHARSET_INFO *cs __attribute__((unused)),
|
||||
while (long_val != 0)
|
||||
{
|
||||
long quo= long_val/10;
|
||||
*--p = '0' + (long_val - quo*10);
|
||||
*--p = (char) ('0' + (long_val - quo*10));
|
||||
long_val= quo;
|
||||
}
|
||||
|
||||
|
@ -512,42 +512,84 @@ static int my_strnxfrm_win1250ch(CHARSET_INFO * cs __attribute__((unused)),
|
||||
|
||||
#ifdef REAL_MYSQL
|
||||
|
||||
static uchar NEAR like_range_prefix_min_win1250ch[] =
|
||||
static uchar NEAR like_range_prefix_min_win1250ch[]=
|
||||
{
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
|
||||
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
|
||||
64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
|
||||
80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
|
||||
96, 54, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
|
||||
80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 165, 124, 125, 126, 0,
|
||||
0, 0, 130, 0, 132, 133, 134, 135, 0, 137, 138, 139, 83, 84, 142, 90,
|
||||
0, 145, 146, 147, 148, 149, 150, 151, 0, 153, 138, 155, 83, 84, 142, 90,
|
||||
32, 161, 162, 76, 164, 165, 166, 167, 168, 65, 83, 171, 172, 173, 174, 90,
|
||||
176, 177, 178, 76, 180, 181, 0, 183, 184, 65, 83, 187, 76, 189, 76, 90,
|
||||
82, 65, 65, 65, 65, 76, 67, 67, 200, 69, 69, 69, 69, 73, 73, 68,
|
||||
68, 78, 78, 79, 79, 79, 79, 215, 216, 85, 85, 85, 85, 89, 84, 223,
|
||||
82, 65, 65, 65, 65, 76, 67, 67, 200, 69, 69, 69, 69, 73, 73, 68,
|
||||
68, 78, 78, 79, 79, 79, 79, 247, 216, 85, 85, 85, 85, 89, 84, 255,
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
|
||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
|
||||
0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
|
||||
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
|
||||
0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
|
||||
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
|
||||
0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
|
||||
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
|
||||
0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
|
||||
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
|
||||
0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
|
||||
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
|
||||
0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
|
||||
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
|
||||
0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
|
||||
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
|
||||
0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
|
||||
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
|
||||
0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
|
||||
0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7,
|
||||
0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
|
||||
0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7,
|
||||
0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
|
||||
0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
|
||||
0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
|
||||
0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7,
|
||||
0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
|
||||
0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
|
||||
0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
|
||||
0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
|
||||
0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF
|
||||
};
|
||||
static uchar NEAR like_range_prefix_max_win1250ch[] = {
|
||||
182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182,
|
||||
182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182,
|
||||
160, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
|
||||
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
|
||||
64, 185, 98, 73, 240, 234, 102, 103, 104, 238, 106, 107, 179, 109, 242, 245,
|
||||
112, 113, 224, 186, 254, 251, 118, 119, 120, 253, 159, 91, 92, 93, 94, 95,
|
||||
96, 54, 98, 73, 240, 234, 102, 103, 104, 238, 106, 107, 179, 109, 242, 245,
|
||||
112, 113, 224, 186, 254, 251, 118, 119, 120, 253, 159, 165, 124, 125, 126, 182,
|
||||
182, 182, 130, 182, 132, 133, 134, 135, 182, 137, 154, 139, 186, 254, 158, 159,
|
||||
182, 145, 146, 147, 148, 149, 150, 151, 182, 153, 154, 155, 186, 254, 158, 159,
|
||||
32, 161, 162, 179, 164, 165, 166, 167, 168, 185, 186, 171, 172, 173, 174, 159,
|
||||
176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 179, 189, 179, 159,
|
||||
224, 185, 185, 185, 185, 179, 238, 238, 200, 234, 234, 234, 234, 238, 238, 240,
|
||||
240, 242, 242, 245, 245, 245, 245, 215, 248, 251, 251, 251, 251, 253, 254, 223,
|
||||
224, 185, 185, 185, 185, 179, 238, 238, 200, 234, 234, 234, 234, 238, 238, 240,
|
||||
240, 242, 242, 245, 245, 245, 245, 247, 248, 251, 251, 251, 251, 253, 254, 255,
|
||||
|
||||
/*
|
||||
The letter "C" is a special case:
|
||||
"CH" is sorted between "H" and "I".
|
||||
prefix_max for "C" is "I": prefix_max[0x43] == 0x49
|
||||
prefix_max for "c" is "i": prefix_max[0x63] == 0x69
|
||||
For all other characters: prefix_max[i] == i
|
||||
*/
|
||||
|
||||
static uchar NEAR like_range_prefix_max_win1250ch[]=
|
||||
{
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
|
||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
|
||||
0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
|
||||
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
|
||||
0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
|
||||
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
|
||||
0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
|
||||
0x40, 0x41, 0x42, 0x49, 0x44, 0x45, 0x46, 0x47,
|
||||
0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
|
||||
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
|
||||
0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
|
||||
0x60, 0x61, 0x62, 0x69, 0x64, 0x65, 0x66, 0x67,
|
||||
0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
|
||||
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
|
||||
0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
|
||||
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
|
||||
0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
|
||||
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
|
||||
0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
|
||||
0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7,
|
||||
0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
|
||||
0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7,
|
||||
0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
|
||||
0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
|
||||
0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
|
||||
0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7,
|
||||
0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
|
||||
0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
|
||||
0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
|
||||
0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
|
||||
0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF
|
||||
};
|
||||
|
||||
#define min_sort_char '\x20'
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user