Commit 06f3d10f authored by unknown's avatar unknown

Merge abotchkov@bk-internal.mysql.com:/home/bk/mysql-4.1

into deer.(none):/home/hf/work/mysql-4.1.2way


BitKeeper/etc/logging_ok:
  auto-union
parents cc090417 ac6fa6e4
...@@ -34,6 +34,7 @@ hf@deer.(none) ...@@ -34,6 +34,7 @@ hf@deer.(none)
hf@deer.mysql.r18.ru hf@deer.mysql.r18.ru
hf@genie.(none) hf@genie.(none)
igor@hundin.mysql.fi igor@hundin.mysql.fi
igor@rurik.mysql.com
jani@dsl-jkl1657.dial.inet.fi jani@dsl-jkl1657.dial.inet.fi
jani@dsl-kpogw4gb5.dial.inet.fi jani@dsl-kpogw4gb5.dial.inet.fi
jani@hynda.(none) jani@hynda.(none)
...@@ -97,6 +98,7 @@ sasha@mysql.sashanet.com ...@@ -97,6 +98,7 @@ sasha@mysql.sashanet.com
serg@build.mysql2.com serg@build.mysql2.com
serg@serg.mylan serg@serg.mylan
serg@serg.mysql.com serg@serg.mysql.com
serg@sergbook.mylan
serg@sergbook.mysql.com serg@sergbook.mysql.com
sinisa@rhols221.adsl.netsonic.fi sinisa@rhols221.adsl.netsonic.fi
tfr@beta.frontier86.ee tfr@beta.frontier86.ee
......
#! /bin/sh
echo "Test: post-incoming works"
#! /bin/sh
echo "Test: post-outgoing works"
#!/bin/sh
if [ "$REAL_EMAIL" = "" ]
then
echo "Error: you must set REAL_EMAIL in your profile"
echo "e.g.: export REAL_EMAIL='Joe Dow <joe@foo.bar>'"
echo ""
echo "Commit FAILED!"
echo "Set REAL_EMAIL and retry."
exit 1
fi
...@@ -10,7 +10,7 @@ This is a simple 'HOWTO' document describing how to ...@@ -10,7 +10,7 @@ This is a simple 'HOWTO' document describing how to
build MySQL binaries for versions 4.1 and above on build MySQL binaries for versions 4.1 and above on
Windows. Instructions are provided for building binaries Windows. Instructions are provided for building binaries
from a standard source distribution or from the BitKeeper from a standard source distribution or from the BitKeeper
tree that contains the latest developer source. tree that contains the latest development source.
--------------------------------------------------------- ---------------------------------------------------------
NOTE NOTE
...@@ -51,29 +51,15 @@ system: ...@@ -51,29 +51,15 @@ system:
- ~45 MB disk space - ~45 MB disk space
- 64 MB RAM - 64 MB RAM
You'll also need a MySQL source distribution. You can You'll also need a MySQL source distribution, which you
get the source for released versions of MySQL from: can obtain as described in section 2.
http://www.mysql.com/downloads/
Alternatively, you can package a source distribution
yourself from the latest BitKeeper developer source
tree. If you plan to do this, you must create the
package on a Unix system and then transfer it to your
Windows system. (The reason for this is that the initial
configuration scripts and some of the build steps work
only on Unix.) The BitKeeper approach thus requires:
- A system running Unix, or a Unix-like system such as Linux
- BitKeeper 3.0 installed on that system (you can obtain
BitKeeper from http://www.bitkeeper.com)
------------------------------------------------------- -------------------------------------------------------
2. OBTAINING A WINDOWS SOURCE DISTRIBUTION 2. OBTAINING A WINDOWS SOURCE DISTRIBUTION
------------------------------------------------------- -------------------------------------------------------
There are two ways you can get a Windows source distribution for There are two ways you can get a Windows source distribution
MySQL version 4.1 and above: for MySQL version 4.1 and above:
I. Obtain a MySQL AB-distributed source distribution for the I. Obtain a MySQL AB-distributed source distribution for the
particular version of MySQL in which you are interested. particular version of MySQL in which you are interested.
...@@ -82,41 +68,54 @@ MySQL version 4.1 and above: ...@@ -82,41 +68,54 @@ MySQL version 4.1 and above:
http://www.mysql.com/downloads/ http://www.mysql.com/downloads/
II. Create a source package yourself from the latest development II. Alternatively, you can package a source distribution
'BitKeeper' source tree. yourself from the latest BitKeeper developer source
tree. If you plan to do this, you must create the
package on a Unix system and then transfer it to your
Windows system. (The reason for this is that some of the
configuration and build steps require tools that work only
on Unix.) The BitKeeper approach thus requires:
- A system running Unix, or a Unix-like system such as Linux
- BitKeeper 3.0 installed on that system (you can obtain
BitKeeper from http://www.bitkeeper.com)
If you are using the first option, you can skip the next If you are using the first option, you can skip the next
section and go directly to 'BUILDING FROM VC++ WORKSPACE'. section and go directly to "BUILDING 'mysql server & clients'
FROM VC++ WORKSPACE"
------------------------------------------------------- -------------------------------------------------------
3. CREATING A SOURCE PACKAGE FROM THE 'BitKeeper' TREE 3. CREATING A SOURCE PACKAGE FROM THE 'BitKeeper' TREE
------------------------------------------------------- -------------------------------------------------------
To build the latest Windows source package, Please follow the To build the latest Windows source package from the current
following instructions from any of your '*UNIX*' operating BitKeeper source tree, use the following instructions. Please
systems (preferably Linux): note that this procedure must be performed on a system
running a Unix or Unix-like operating system. (The procedure
is know to work well on Linux, for example.
- Clone the BitKeeper source tree for MySQL (version 4.1 - Clone the BitKeeper source tree for MySQL (version 4.1
or above, as desired). For more information how to clone or above, as desired). For more information how to clone
the BitKeeper source tree, follow the instructions at: the source tree, see the instructions at:
http://www.mysql.com/doc/en/Installing_source_tree.html http://www.mysql.com/doc/en/Installing_source_tree.html
- Build the distribution so that you have a server binary to - Configure and build the distribution so that you have a
work with. One way to do this is to run the following server binary to work with. One way to do this is to run
command in the top-level directory of your source tree: the following command in the top-level directory of your
source tree:
./BUILD/compile-pentium-max ./BUILD/compile-pentium-max
- After making sure that build process completed successfully, - After making sure that the build process completed successfully,
run the following utility script from top-level directory run the following utility script from top-level directory
of your source tree: of your source tree:
./scripts/make_win_src_distribution ./scripts/make_win_src_distribution
This script creates the Windows source package. You can This script creates a Windows source package, to be used on
supply different options to the script based on your needs. your Windows system. You can supply different options to the
It accepts: the following options: script based on your needs. It accepts the following options:
--debug Debug, without creating the package --debug Debug, without creating the package
--tmp Specify the temporary location --tmp Specify the temporary location
...@@ -128,15 +127,14 @@ systems (preferably Linux): ...@@ -128,15 +127,14 @@ systems (preferably Linux):
By default, make_win_src_distribution creates a zipped By default, make_win_src_distribution creates a zipped
archive with the name mysql-$version-win-src.zip, where archive with the name mysql-$version-win-src.zip, where
$version is the version of the MySQL source tree you $version represents the version of your MySQL source tree.
cloned.
- Copy or upload to your Windows machine the Windows source - Copy or upload to your Windows machine the Windows source
package that you have just created, and compile it using package that you have just created. To compile it, use
the instructions in the next section. the instructions in the next section.
--------------------------------------------------------- ---------------------------------------------------------
4. BUILDING 'mysql server & clients' FROM VC++ WORKSPACE 4. BUILDING 'mysql server & clients' FROM VC++ WORKSPACE
--------------------------------------------------------- ---------------------------------------------------------
NOTE: MySQL 4.1 and above VC++ workspace files are compatible NOTE: MySQL 4.1 and above VC++ workspace files are compatible
...@@ -148,20 +146,20 @@ Unpack the Windows source zipped archive to a folder and open ...@@ -148,20 +146,20 @@ Unpack the Windows source zipped archive to a folder and open
mysql.dsw from your top-level directory. mysql.dsw from your top-level directory.
If you want to build both release and debug versions, then If you want to build both release and debug versions, then
select 'build' -> 'buildall' option. To build only 'release' select 'build' -> 'buildall' option. To build only release
or 'debug' versions, then select all appropriate workspaces or debug versions, select all appropriate workspaces from
from the 'build' -> 'batch build' option. the 'build' -> 'batch build' option.
The simplest solution to build basic clients and core The simplest solution to building the basic clients and core
server is to set your current active workspace as 'mysqld' server is to set your current active workspace as 'mysqld'
release or debug version, and just hit 'build' or 'F7', which release or debug version, and just hit 'build' or 'F7', which
creates necessary client binaries in the 'client_release' or creates the necessary client binaries in the 'client_release'
'client_debug' directories. The libraries are placed in the or 'client_debug' directories. The libraries are placed in the
'lib_release' and 'lib_debug' directories for release and 'lib_release' and 'lib_debug' directories for release and
debug versions, respectively. debug versions, respectively.
Now you have built the distribution. If you get any compiler Now you have built the distribution. If you get any compiler
errors, please cross check and send the compiler output to errors, please cross check and email the compiler output to
win32@lists.mysql.com for further assistance. win32@lists.mysql.com for further assistance.
--------------------------------------------------------- ---------------------------------------------------------
...@@ -173,16 +171,28 @@ TODO from MySQL PIEFU team. ...@@ -173,16 +171,28 @@ TODO from MySQL PIEFU team.
6. STARTING THE MYSQL SERVER FOR THE FIRST TIME 6. STARTING THE MYSQL SERVER FOR THE FIRST TIME
--------------------------------------------------------- ---------------------------------------------------------
First ensure to set or copy my.ini or my.cnf file to your The server built using the preceding instructions will
'data' directory that exists in the top-level directory or expect that the MySQL base directory and data directory
point to existing 'data' directory. are C:\mysql and C:\mysql\data by default. If you want to
test your server using the source root directory and its
Now, start your server from the 'client_release' or data directory as the base directory and data directory,
'client_debug' directory (depending on which server you you will need to tell the server their pathnames. You can
want to use), by following the instructions from: either do this on the command line with the --basedir
and --data-dir options, or place appropriate options in
an option file (C:\my.cnf or the my.ini file in your
Windows directory). If you have an existing data directory
elsewhere that you want to use, you can specify its pathname
instead.
Start your server from the 'client_release' or 'client_debug'
directory (depending on which server you want to use). The
general instructions are given here:
http://www.mysql.com/doc/en/Windows_installation.html http://www.mysql.com/doc/en/Windows_installation.html
You'll have to adapt the instructions appropriately if you
want to use a different base directory and/or data directory.
That's all!!! See, it's as simple to build MySQL on Windows That's all!!! See, it's as simple to build MySQL on Windows
as on any other platform!!! as on any other platform!!!
...@@ -200,12 +210,12 @@ exists in your 'client_release' or 'client_debug' directory. ...@@ -200,12 +210,12 @@ exists in your 'client_release' or 'client_debug' directory.
--------------------------------------------------------- ---------------------------------------------------------
- For production use, MySQL AB does not advise using a MySQL - For production use, MySQL AB does not advise using a MySQL
server built by yourself from source. Instead, stick to server built by yourself from source. It is preferable to
binaries shipped by MySQL AB. stick to using binaries shipped by MySQL AB.
- If you find something not working as expected, or you have - If you find something not working as expected, or you have
suggestions about ways to improve the current build process suggestions about ways to improve the current build process
on Windows, please email to 'win32@lists.mysql.com'. on Windows, please email to win32@lists.mysql.com.
Thanks Thanks
MySQL Team MySQL Team
...@@ -22,7 +22,7 @@ AUTOMAKE_OPTIONS = foreign ...@@ -22,7 +22,7 @@ AUTOMAKE_OPTIONS = foreign
EXTRA_DIST = INSTALL-SOURCE README \ EXTRA_DIST = INSTALL-SOURCE README \
COPYING COPYING.LIB COPYING COPYING.LIB
SUBDIRS = . include @docs_dirs@ \ SUBDIRS = . include @docs_dirs@ \
@readline_topdir@ \ @readline_topdir@ sql-common \
@thread_dirs@ pstack @sql_client_dirs@ \ @thread_dirs@ pstack @sql_client_dirs@ \
@sql_server_dirs@ scripts man tests \ @sql_server_dirs@ scripts man tests \
BUILD @netware_dir@ os2 @libmysqld_dirs@ \ BUILD @netware_dir@ os2 @libmysqld_dirs@ \
......
...@@ -2176,8 +2176,8 @@ AC_ARG_WITH(libedit, ...@@ -2176,8 +2176,8 @@ AC_ARG_WITH(libedit,
[ with_libedit=undefined ] [ with_libedit=undefined ]
) )
compile_readline= no compile_readline="no"
compile_libedit= no compile_libedit="no"
if [test "$with_libedit" = "yes"] && [test "$with_readline" = "yes"] if [test "$with_libedit" = "yes"] && [test "$with_readline" = "yes"]
then then
...@@ -2820,6 +2820,7 @@ AC_OUTPUT(Makefile extra/Makefile mysys/Makefile isam/Makefile dnl ...@@ -2820,6 +2820,7 @@ AC_OUTPUT(Makefile extra/Makefile mysys/Makefile isam/Makefile dnl
libmysql_r/Makefile libmysqld/Makefile libmysqld/examples/Makefile dnl libmysql_r/Makefile libmysqld/Makefile libmysqld/examples/Makefile dnl
libmysql/Makefile client/Makefile dnl libmysql/Makefile client/Makefile dnl
pstack/Makefile pstack/aout/Makefile sql/Makefile sql/share/Makefile dnl pstack/Makefile pstack/aout/Makefile sql/Makefile sql/share/Makefile dnl
sql-common/Makefile dnl
merge/Makefile dbug/Makefile scripts/Makefile dnl merge/Makefile dbug/Makefile scripts/Makefile dnl
include/Makefile sql-bench/Makefile tools/Makefile dnl include/Makefile sql-bench/Makefile tools/Makefile dnl
tests/Makefile Docs/Makefile support-files/Makefile dnl tests/Makefile Docs/Makefile support-files/Makefile dnl
...@@ -2840,6 +2841,7 @@ echo "Remember to check the platform specific part of the reference manual for" ...@@ -2840,6 +2841,7 @@ echo "Remember to check the platform specific part of the reference manual for"
echo "hints about installing MySQL on your platform. Also have a look at the" echo "hints about installing MySQL on your platform. Also have a look at the"
echo "files in the Docs directory." echo "files in the Docs directory."
echo echo
# The following text is checked in ./Do-compile to se that the configure ends. # The following text is checked in ./Do-compile to verify that configure
# ended sucessfully - don't remove it.
echo "Thank you for choosing MySQL!" echo "Thank you for choosing MySQL!"
echo echo
...@@ -21,7 +21,7 @@ pkginclude_HEADERS = my_dbug.h m_string.h my_sys.h my_list.h my_xml.h \ ...@@ -21,7 +21,7 @@ pkginclude_HEADERS = my_dbug.h m_string.h my_sys.h my_list.h my_xml.h \
my_semaphore.h my_pthread.h my_no_pthread.h raid.h \ my_semaphore.h my_pthread.h my_no_pthread.h raid.h \
errmsg.h my_global.h my_net.h my_alloc.h \ errmsg.h my_global.h my_net.h my_alloc.h \
my_getopt.h sslopt-longopts.h my_dir.h typelib.h \ my_getopt.h sslopt-longopts.h my_dir.h typelib.h \
sslopt-vars.h sslopt-case.h $(BUILT_SOURCES) sslopt-vars.h sslopt-case.h sql_common.h $(BUILT_SOURCES)
noinst_HEADERS = config-win.h config-os2.h config-netware.h \ noinst_HEADERS = config-win.h config-os2.h config-netware.h \
nisam.h heap.h merge.h my_bitmap.h\ nisam.h heap.h merge.h my_bitmap.h\
myisam.h myisampack.h myisammrg.h ft_global.h\ myisam.h myisampack.h myisammrg.h ft_global.h\
......
...@@ -123,7 +123,8 @@ enum ha_extra_function { ...@@ -123,7 +123,8 @@ enum ha_extra_function {
HA_EXTRA_NO_IGNORE_DUP_KEY, HA_EXTRA_NO_IGNORE_DUP_KEY,
HA_EXTRA_DONT_USE_CURSOR_TO_UPDATE, /* Cursor will not be used for update */ HA_EXTRA_DONT_USE_CURSOR_TO_UPDATE, /* Cursor will not be used for update */
HA_EXTRA_PREPARE_FOR_DELETE, HA_EXTRA_PREPARE_FOR_DELETE,
HA_EXTRA_PREPARE_FOR_UPDATE /* Remove read cache if problems */ HA_EXTRA_PREPARE_FOR_UPDATE, /* Remove read cache if problems */
HA_EXTRA_PRELOAD_BUFFER_SIZE /* Set buffer size for preloading */
}; };
/* The following is parameter to ha_panic() */ /* The following is parameter to ha_panic() */
...@@ -256,6 +257,7 @@ enum ha_base_keytype { ...@@ -256,6 +257,7 @@ enum ha_base_keytype {
#define HA_ERR_CANNOT_ADD_FOREIGN 150 /* Cannot add a foreign key constr. */ #define HA_ERR_CANNOT_ADD_FOREIGN 150 /* Cannot add a foreign key constr. */
#define HA_ERR_NO_REFERENCED_ROW 151 /* Cannot add a child row */ #define HA_ERR_NO_REFERENCED_ROW 151 /* Cannot add a child row */
#define HA_ERR_ROW_IS_REFERENCED 152 /* Cannot delete a parent row */ #define HA_ERR_ROW_IS_REFERENCED 152 /* Cannot delete a parent row */
#define HA_ERR_NON_UNIQUE_BLOCK_SIZE 153 /* Non unique key block size */
/* Other constants */ /* Other constants */
......
...@@ -643,6 +643,8 @@ extern int init_key_cache(ulong use_mem); ...@@ -643,6 +643,8 @@ extern int init_key_cache(ulong use_mem);
extern int resize_key_cache(ulong use_mem); extern int resize_key_cache(ulong use_mem);
extern byte *key_cache_read(File file,my_off_t filepos,byte* buff,uint length, extern byte *key_cache_read(File file,my_off_t filepos,byte* buff,uint length,
uint block_length,int return_buffer); uint block_length,int return_buffer);
extern int key_cache_insert(File file, my_off_t filepos,
byte *buff, uint length);
extern int key_cache_write(File file,my_off_t filepos,byte* buff,uint length, extern int key_cache_write(File file,my_off_t filepos,byte* buff,uint length,
uint block_length,int force_write); uint block_length,int force_write);
extern int flush_key_blocks(int file, enum flush_type type); extern int flush_key_blocks(int file, enum flush_type type);
......
...@@ -410,6 +410,7 @@ my_bool mi_test_if_sort_rep(MI_INFO *info, ha_rows rows, ulonglong key_map, ...@@ -410,6 +410,7 @@ my_bool mi_test_if_sort_rep(MI_INFO *info, ha_rows rows, ulonglong key_map,
int mi_init_bulk_insert(MI_INFO *info, ulong cache_size, ha_rows rows); int mi_init_bulk_insert(MI_INFO *info, ulong cache_size, ha_rows rows);
void mi_flush_bulk_insert(MI_INFO *info, uint inx); void mi_flush_bulk_insert(MI_INFO *info, uint inx);
void mi_end_bulk_insert(MI_INFO *info); void mi_end_bulk_insert(MI_INFO *info);
int mi_preload(MI_INFO *info, ulonglong key_map, my_bool ignore_leaves);
#ifdef __cplusplus #ifdef __cplusplus
} }
......
...@@ -28,6 +28,7 @@ libmysqlclient_la_SOURCES = $(target_sources) ...@@ -28,6 +28,7 @@ libmysqlclient_la_SOURCES = $(target_sources)
libmysqlclient_la_LIBADD = $(target_libadd) libmysqlclient_la_LIBADD = $(target_libadd)
libmysqlclient_la_LDFLAGS = $(target_ldflags) libmysqlclient_la_LDFLAGS = $(target_ldflags)
EXTRA_DIST = Makefile.shared EXTRA_DIST = Makefile.shared
noinst_HEADERS = client_settings.h
# This is called from the toplevel makefile # This is called from the toplevel makefile
link_sources: link_sources:
......
...@@ -47,6 +47,7 @@ libmyisam_a_SOURCES = mi_open.c mi_extra.c mi_info.c mi_rkey.c \ ...@@ -47,6 +47,7 @@ libmyisam_a_SOURCES = mi_open.c mi_extra.c mi_info.c mi_rkey.c \
mi_range.c mi_dbug.c mi_checksum.c mi_log.c \ mi_range.c mi_dbug.c mi_checksum.c mi_log.c \
mi_changed.c mi_static.c mi_delete_all.c \ mi_changed.c mi_static.c mi_delete_all.c \
mi_delete_table.c mi_rename.c mi_check.c \ mi_delete_table.c mi_rename.c mi_check.c \
mi_preload.c \
ft_parser.c ft_stopwords.c ft_static.c \ ft_parser.c ft_stopwords.c ft_static.c \
ft_update.c ft_boolean_search.c ft_nlq_search.c sort.c \ ft_update.c ft_boolean_search.c ft_nlq_search.c sort.c \
rt_index.c rt_key.c rt_mbr.c rt_split.c sp_key.c rt_index.c rt_key.c rt_mbr.c rt_split.c sp_key.c
......
...@@ -367,6 +367,9 @@ int mi_extra(MI_INFO *info, enum ha_extra_function function, void *extra_arg) ...@@ -367,6 +367,9 @@ int mi_extra(MI_INFO *info, enum ha_extra_function function, void *extra_arg)
if (!share->state.header.uniques) if (!share->state.header.uniques)
info->opt_flag|= OPT_NO_ROWS; info->opt_flag|= OPT_NO_ROWS;
break; break;
case HA_EXTRA_PRELOAD_BUFFER_SIZE:
info->preload_buff_size= *((ulong *) extra_arg);
break;
case HA_EXTRA_KEY_CACHE: case HA_EXTRA_KEY_CACHE:
case HA_EXTRA_NO_KEY_CACHE: case HA_EXTRA_NO_KEY_CACHE:
default: default:
......
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
Preload indexes into key cache
*/
#include "myisamdef.h"
/*
Preload pages of the index file for a table into the key cache
SYNOPSIS
mi_preload()
info open table
map map of indexes to preload into key cache
ignore_leaves only non-leaves pages are to be preloaded
RETURN VALUE
0 if a success. error code - otherwise.
NOTES.
At present pages for all indexes are preloaded.
In future only pages for indexes specified in the key_map parameter
of the table will be preloaded.
*/
int mi_preload(MI_INFO *info, ulonglong key_map, my_bool ignore_leaves)
{
uint i;
uint length;
uint block_length= 0;
uchar *buff= NULL;
MYISAM_SHARE* share= info->s;
uint keys= share->state.header.keys;
MI_KEYDEF *keyinfo= share->keyinfo;
my_off_t key_file_length= share->state.state.key_file_length;
my_off_t pos= share->base.keystart;
if (!keys || !key_map || key_file_length == pos)
return 0;
block_length= keyinfo[0].block_length;
if (!key_map)
return 0;
/* Check whether all indexes use the same block size */
for (i= 1 ; i < keys ; i++)
{
if (keyinfo[i].block_length != block_length)
return (my_errno= HA_ERR_NON_UNIQUE_BLOCK_SIZE);
}
length= info->preload_buff_size/block_length * block_length;
set_if_bigger(length, block_length);
if (!(buff= (uchar *) my_malloc(length, MYF(MY_WME))))
return (my_errno= HA_ERR_OUT_OF_MEM);
if (flush_key_blocks(share->kfile, FLUSH_RELEASE))
goto err;
do
{
/* Read the next block of index file into the preload buffer */
set_if_smaller(length, key_file_length-pos);
if (my_pread(share->kfile, (byte*) buff, length, pos, MYF(MY_FAE)))
goto err;
if (ignore_leaves)
{
uchar *end= buff+length;
do
{
if (mi_test_if_nod(buff))
{
if (key_cache_insert(share->kfile, pos, (byte*) buff, block_length))
goto err;
}
pos+= block_length;
}
while ((buff+= block_length) != end);
buff= end-length;
}
else
{
if (key_cache_insert(share->kfile, pos, (byte*) buff, length))
goto err;
pos+= length;
}
}
while (pos != key_file_length);
my_free(buff, MYF(0));
return 0;
err:
my_free(buff, MYF(MY_ALLOW_ZERO_PTR));
return (my_errno= errno);
}
...@@ -262,6 +262,7 @@ struct st_myisam_info { ...@@ -262,6 +262,7 @@ struct st_myisam_info {
int save_lastinx; int save_lastinx;
LIST open_list; LIST open_list;
IO_CACHE rec_cache; /* When cacheing records */ IO_CACHE rec_cache; /* When cacheing records */
uint preload_buff_size; /* When preloading indexes */
myf lock_wait; /* is 0 or MY_DONT_WAIT */ myf lock_wait; /* is 0 or MY_DONT_WAIT */
my_bool was_locked; /* Was locked in panic */ my_bool was_locked; /* Was locked in panic */
my_bool quick_mode; my_bool quick_mode;
......
...@@ -249,6 +249,24 @@ INSERT INTO t1 VALUES (1, 'a545f661efdd1fb66fdee3aab79945bf'); ...@@ -249,6 +249,24 @@ INSERT INTO t1 VALUES (1, 'a545f661efdd1fb66fdee3aab79945bf');
SELECT 1 FROM t1 WHERE tmp=AES_DECRYPT(tmp,"password"); SELECT 1 FROM t1 WHERE tmp=AES_DECRYPT(tmp,"password");
1 1
DROP TABLE t1; DROP TABLE t1;
select collation(bin(130)), coercibility(bin(130));
collation(bin(130)) coercibility(bin(130))
latin1_swedish_ci 3
select collation(oct(130)), coercibility(oct(130));
collation(oct(130)) coercibility(oct(130))
latin1_swedish_ci 3
select collation(conv(130,16,10)), coercibility(conv(130,16,10));
collation(conv(130,16,10)) coercibility(conv(130,16,10))
latin1_swedish_ci 3
select collation(hex(130)), coercibility(hex(130));
collation(hex(130)) coercibility(hex(130))
latin1_swedish_ci 3
select collation(char(130)), coercibility(hex(130));
collation(char(130)) coercibility(hex(130))
binary 3
select collation(format(130,10)), coercibility(format(130,10));
collation(format(130,10)) coercibility(format(130,10))
latin1_swedish_ci 3
select collation(lcase(_latin2'a')), coercibility(lcase(_latin2'a')); select collation(lcase(_latin2'a')), coercibility(lcase(_latin2'a'));
collation(lcase(_latin2'a')) coercibility(lcase(_latin2'a')) collation(lcase(_latin2'a')) coercibility(lcase(_latin2'a'))
latin2_general_ci 3 latin2_general_ci 3
...@@ -267,9 +285,21 @@ latin2_general_ci 3 ...@@ -267,9 +285,21 @@ latin2_general_ci 3
select collation(concat(_latin2'a',_latin2'b')), coercibility(concat(_latin2'a',_latin2'b')); select collation(concat(_latin2'a',_latin2'b')), coercibility(concat(_latin2'a',_latin2'b'));
collation(concat(_latin2'a',_latin2'b')) coercibility(concat(_latin2'a',_latin2'b')) collation(concat(_latin2'a',_latin2'b')) coercibility(concat(_latin2'a',_latin2'b'))
latin2_general_ci 3 latin2_general_ci 3
select collation(lpad(_latin2'a',4,_latin2'b')), coercibility(lpad(_latin2'a',4,_latin2'b'));
collation(lpad(_latin2'a',4,_latin2'b')) coercibility(lpad(_latin2'a',4,_latin2'b'))
binary 3
select collation(rpad(_latin2'a',4,_latin2'b')), coercibility(rpad(_latin2'a',4,_latin2'b'));
collation(rpad(_latin2'a',4,_latin2'b')) coercibility(rpad(_latin2'a',4,_latin2'b'))
latin2_general_ci 3
select collation(concat_ws(_latin2'a',_latin2'b')), coercibility(concat_ws(_latin2'a',_latin2'b')); select collation(concat_ws(_latin2'a',_latin2'b')), coercibility(concat_ws(_latin2'a',_latin2'b'));
collation(concat_ws(_latin2'a',_latin2'b')) coercibility(concat_ws(_latin2'a',_latin2'b')) collation(concat_ws(_latin2'a',_latin2'b')) coercibility(concat_ws(_latin2'a',_latin2'b'))
latin2_general_ci 3 latin2_general_ci 3
select collation(make_set(255,_latin2'a',_latin2'b',_latin2'c')), coercibility(make_set(255,_latin2'a',_latin2'b',_latin2'c'));
collation(make_set(255,_latin2'a',_latin2'b',_latin2'c')) coercibility(make_set(255,_latin2'a',_latin2'b',_latin2'c'))
latin2_general_ci 3
select collation(export_set(255,_latin2'y',_latin2'n',_latin2' ')), coercibility(export_set(255,_latin2'y',_latin2'n',_latin2' '));
collation(export_set(255,_latin2'y',_latin2'n',_latin2' ')) coercibility(export_set(255,_latin2'y',_latin2'n',_latin2' '))
binary 3
select collation(trim(_latin2' a ')), coercibility(trim(_latin2' a ')); select collation(trim(_latin2' a ')), coercibility(trim(_latin2' a '));
collation(trim(_latin2' a ')) coercibility(trim(_latin2' a ')) collation(trim(_latin2' a ')) coercibility(trim(_latin2' a '))
latin2_general_ci 3 latin2_general_ci 3
...@@ -306,15 +336,28 @@ latin2_general_ci 3 ...@@ -306,15 +336,28 @@ latin2_general_ci 3
select collation(insert(_latin2'abcd',2,3,_latin2'ef')), coercibility(insert(_latin2'abcd',2,3,_latin2'ef')); select collation(insert(_latin2'abcd',2,3,_latin2'ef')), coercibility(insert(_latin2'abcd',2,3,_latin2'ef'));
collation(insert(_latin2'abcd',2,3,_latin2'ef')) coercibility(insert(_latin2'abcd',2,3,_latin2'ef')) collation(insert(_latin2'abcd',2,3,_latin2'ef')) coercibility(insert(_latin2'abcd',2,3,_latin2'ef'))
latin2_general_ci 3 latin2_general_ci 3
select collation(replace(_latin2'abcd',_latin2'b',_latin2'B')), coercibility(replace(_latin2'abcd',_latin2'b',_latin2'B'));
collation(replace(_latin2'abcd',_latin2'b',_latin2'B')) coercibility(replace(_latin2'abcd',_latin2'b',_latin2'B'))
latin2_general_ci 3
create table t1 create table t1
select select
bin(130),
oct(130),
conv(130,16,10),
hex(130),
char(130),
format(130,10),
left(_latin2'a',1), left(_latin2'a',1),
right(_latin2'a',1), right(_latin2'a',1),
lcase(_latin2'a'), lcase(_latin2'a'),
ucase(_latin2'a'), ucase(_latin2'a'),
substring(_latin2'a',1,1), substring(_latin2'a',1,1),
concat(_latin2'a',_latin2'b'), concat(_latin2'a',_latin2'b'),
lpad(_latin2'a',4,_latin2'b'),
rpad(_latin2'a',4,_latin2'b'),
concat_ws(_latin2'a',_latin2'b'), concat_ws(_latin2'a',_latin2'b'),
make_set(255,_latin2'a',_latin2'b',_latin2'c'),
export_set(255,_latin2'y',_latin2'n',_latin2' '),
trim(_latin2' a '), trim(_latin2' a '),
ltrim(_latin2' a '), ltrim(_latin2' a '),
rtrim(_latin2' a '), rtrim(_latin2' a '),
...@@ -326,18 +369,31 @@ reverse(_latin2'ab'), ...@@ -326,18 +369,31 @@ reverse(_latin2'ab'),
quote(_latin2'ab'), quote(_latin2'ab'),
soundex(_latin2'ab'), soundex(_latin2'ab'),
substring(_latin2'ab',1), substring(_latin2'ab',1),
insert(_latin2'abcd',2,3,_latin2'ef') insert(_latin2'abcd',2,3,_latin2'ef'),
replace(_latin2'abcd',_latin2'b',_latin2'B')
; ;
Warnings:
Warning 1263 Data truncated for column 'format(130,10)' at row 1
show create table t1; show create table t1;
Table Create Table Table Create Table
t1 CREATE TABLE `t1` ( t1 CREATE TABLE `t1` (
`bin(130)` char(64) NOT NULL default '',
`oct(130)` char(64) NOT NULL default '',
`conv(130,16,10)` char(64) NOT NULL default '',
`hex(130)` char(6) NOT NULL default '',
`char(130)` char(1) NOT NULL default '',
`format(130,10)` char(4) NOT NULL default '',
`left(_latin2'a',1)` char(1) character set latin2 NOT NULL default '', `left(_latin2'a',1)` char(1) character set latin2 NOT NULL default '',
`right(_latin2'a',1)` char(1) character set latin2 NOT NULL default '', `right(_latin2'a',1)` char(1) character set latin2 NOT NULL default '',
`lcase(_latin2'a')` char(1) character set latin2 NOT NULL default '', `lcase(_latin2'a')` char(1) character set latin2 NOT NULL default '',
`ucase(_latin2'a')` char(1) character set latin2 NOT NULL default '', `ucase(_latin2'a')` char(1) character set latin2 NOT NULL default '',
`substring(_latin2'a',1,1)` char(1) character set latin2 NOT NULL default '', `substring(_latin2'a',1,1)` char(1) character set latin2 NOT NULL default '',
`concat(_latin2'a',_latin2'b')` char(2) character set latin2 NOT NULL default '', `concat(_latin2'a',_latin2'b')` char(2) character set latin2 NOT NULL default '',
`lpad(_latin2'a',4,_latin2'b')` char(4) character set latin2 NOT NULL default '',
`rpad(_latin2'a',4,_latin2'b')` char(4) character set latin2 NOT NULL default '',
`concat_ws(_latin2'a',_latin2'b')` char(1) character set latin2 NOT NULL default '', `concat_ws(_latin2'a',_latin2'b')` char(1) character set latin2 NOT NULL default '',
`make_set(255,_latin2'a',_latin2'b',_latin2'c')` char(5) character set latin2 NOT NULL default '',
`export_set(255,_latin2'y',_latin2'n',_latin2' ')` char(127) character set latin2 NOT NULL default '',
`trim(_latin2' a ')` char(3) character set latin2 NOT NULL default '', `trim(_latin2' a ')` char(3) character set latin2 NOT NULL default '',
`ltrim(_latin2' a ')` char(3) character set latin2 NOT NULL default '', `ltrim(_latin2' a ')` char(3) character set latin2 NOT NULL default '',
`rtrim(_latin2' a ')` char(3) character set latin2 NOT NULL default '', `rtrim(_latin2' a ')` char(3) character set latin2 NOT NULL default '',
...@@ -349,6 +405,7 @@ t1 CREATE TABLE `t1` ( ...@@ -349,6 +405,7 @@ t1 CREATE TABLE `t1` (
`quote(_latin2'ab')` char(6) character set latin2 NOT NULL default '', `quote(_latin2'ab')` char(6) character set latin2 NOT NULL default '',
`soundex(_latin2'ab')` char(4) character set latin2 NOT NULL default '', `soundex(_latin2'ab')` char(4) character set latin2 NOT NULL default '',
`substring(_latin2'ab',1)` char(2) character set latin2 NOT NULL default '', `substring(_latin2'ab',1)` char(2) character set latin2 NOT NULL default '',
`insert(_latin2'abcd',2,3,_latin2'ef')` char(6) character set latin2 NOT NULL default '' `insert(_latin2'abcd',2,3,_latin2'ef')` char(6) character set latin2 NOT NULL default '',
`replace(_latin2'abcd',_latin2'b',_latin2'B')` char(4) character set latin2 NOT NULL default ''
) TYPE=MyISAM CHARSET=latin1 ) TYPE=MyISAM CHARSET=latin1
drop table t1; drop table t1;
drop table if exists t1, t2;
create table t1 (
a int not null auto_increment,
b char(16) not null,
primary key (a),
key (b)
);
create table t2(
a int not null auto_increment,
b char(16) not null,
primary key (a),
key (b)
);
insert into t1(b) values
('test0'),
('test1'),
('test2'),
('test3'),
('test4'),
('test5'),
('test6'),
('test7');
insert into t2(b) select b from t1;
insert into t1(b) select b from t2;
insert into t2(b) select b from t1;
insert into t1(b) select b from t2;
insert into t2(b) select b from t1;
insert into t1(b) select b from t2;
insert into t2(b) select b from t1;
insert into t1(b) select b from t2;
insert into t2(b) select b from t1;
insert into t1(b) select b from t2;
insert into t2(b) select b from t1;
insert into t1(b) select b from t2;
insert into t2(b) select b from t1;
insert into t1(b) select b from t2;
insert into t2(b) select b from t1;
insert into t1(b) select b from t2;
insert into t2(b) select b from t1;
insert into t1(b) select b from t2;
select count(*) from t1;
count(*)
33448
select count(*) from t2;
count(*)
20672
flush tables;
flush status;
show status like "key_read%";
Variable_name Value
Key_read_requests 0
Key_reads 0
select count(*) from t1 where b = 'test1';
count(*)
4181
show status like "key_read%";
Variable_name Value
Key_read_requests 217
Key_reads 45
select count(*) from t1 where b = 'test1';
count(*)
4181
show status like "key_read%";
Variable_name Value
Key_read_requests 434
Key_reads 45
flush tables;
flush status;
select @@preload_buffer_size;
@@preload_buffer_size
32768
load index into cache t1 keys;
Table Op Msg_type Msg_text
test.t1 preload_keys status OK
show status like "key_read%";
Variable_name Value
Key_read_requests 0
Key_reads 0
select count(*) from t1 where b = 'test1';
count(*)
4181
show status like "key_read%";
Variable_name Value
Key_read_requests 217
Key_reads 45
flush tables;
flush status;
show status like "key_read%";
Variable_name Value
Key_read_requests 0
Key_reads 0
set session preload_buffer_size=256*1024;
select @@preload_buffer_size;
@@preload_buffer_size
262144
load index into cache t1 keys ignore leaves;
Table Op Msg_type Msg_text
test.t1 preload_keys status OK
show status like "key_read%";
Variable_name Value
Key_read_requests 0
Key_reads 0
select count(*) from t1 where b = 'test1';
count(*)
4181
show status like "key_read%";
Variable_name Value
Key_read_requests 217
Key_reads 45
flush tables;
flush status;
show status like "key_read%";
Variable_name Value
Key_read_requests 0
Key_reads 0
set session preload_buffer_size=1*1024;
select @@preload_buffer_size;
@@preload_buffer_size
1024
load index into cache t1 keys, t2 keys (primary,b) ignore leaves;
Table Op Msg_type Msg_text
test.t1 preload_keys status OK
test.t2 preload_keys status OK
show status like "key_read%";
Variable_name Value
Key_read_requests 0
Key_reads 0
select count(*) from t1 where b = 'test1';
count(*)
4181
select count(*) from t2 where b = 'test1';
count(*)
2584
show status like "key_read%";
Variable_name Value
Key_read_requests 351
Key_reads 73
flush tables;
flush status;
show status like "key_read%";
Variable_name Value
Key_read_requests 0
Key_reads 0
load index into cache t3 keys, t2 keys (primary,b) ;
Table Op Msg_type Msg_text
test.t3 preload_keys error Table 'test.t3' doesn't exist
test.t2 preload_keys status OK
show status like "key_read%";
Variable_name Value
Key_read_requests 0
Key_reads 0
flush tables;
flush status;
show status like "key_read%";
Variable_name Value
Key_read_requests 0
Key_reads 0
load index into cache t3 keys (b), t2 keys (c) ;
Table Op Msg_type Msg_text
test.t3 preload_keys error Table 'test.t3' doesn't exist
test.t2 preload_keys error Key column 'c' doesn't exist in table
test.t2 preload_keys status Operation failed
show status like "key_read%";
Variable_name Value
Key_read_requests 0
Key_reads 0
drop table t1, t2;
...@@ -136,13 +136,23 @@ DROP TABLE t1; ...@@ -136,13 +136,23 @@ DROP TABLE t1;
# #
# Test collation and coercibility # Test collation and coercibility
# #
select collation(bin(130)), coercibility(bin(130));
select collation(oct(130)), coercibility(oct(130));
select collation(conv(130,16,10)), coercibility(conv(130,16,10));
select collation(hex(130)), coercibility(hex(130));
select collation(char(130)), coercibility(hex(130));
select collation(format(130,10)), coercibility(format(130,10));
select collation(lcase(_latin2'a')), coercibility(lcase(_latin2'a')); select collation(lcase(_latin2'a')), coercibility(lcase(_latin2'a'));
select collation(ucase(_latin2'a')), coercibility(ucase(_latin2'a')); select collation(ucase(_latin2'a')), coercibility(ucase(_latin2'a'));
select collation(left(_latin2'a',1)), coercibility(left(_latin2'a',1)); select collation(left(_latin2'a',1)), coercibility(left(_latin2'a',1));
select collation(right(_latin2'a',1)), coercibility(right(_latin2'a',1)); select collation(right(_latin2'a',1)), coercibility(right(_latin2'a',1));
select collation(substring(_latin2'a',1,1)), coercibility(substring(_latin2'a',1,1)); select collation(substring(_latin2'a',1,1)), coercibility(substring(_latin2'a',1,1));
select collation(concat(_latin2'a',_latin2'b')), coercibility(concat(_latin2'a',_latin2'b')); select collation(concat(_latin2'a',_latin2'b')), coercibility(concat(_latin2'a',_latin2'b'));
select collation(lpad(_latin2'a',4,_latin2'b')), coercibility(lpad(_latin2'a',4,_latin2'b'));
select collation(rpad(_latin2'a',4,_latin2'b')), coercibility(rpad(_latin2'a',4,_latin2'b'));
select collation(concat_ws(_latin2'a',_latin2'b')), coercibility(concat_ws(_latin2'a',_latin2'b')); select collation(concat_ws(_latin2'a',_latin2'b')), coercibility(concat_ws(_latin2'a',_latin2'b'));
select collation(make_set(255,_latin2'a',_latin2'b',_latin2'c')), coercibility(make_set(255,_latin2'a',_latin2'b',_latin2'c'));
select collation(export_set(255,_latin2'y',_latin2'n',_latin2' ')), coercibility(export_set(255,_latin2'y',_latin2'n',_latin2' '));
select collation(trim(_latin2' a ')), coercibility(trim(_latin2' a ')); select collation(trim(_latin2' a ')), coercibility(trim(_latin2' a '));
select collation(ltrim(_latin2' a ')), coercibility(ltrim(_latin2' a ')); select collation(ltrim(_latin2' a ')), coercibility(ltrim(_latin2' a '));
select collation(rtrim(_latin2' a ')), coercibility(rtrim(_latin2' a ')); select collation(rtrim(_latin2' a ')), coercibility(rtrim(_latin2' a '));
...@@ -155,16 +165,27 @@ select collation(quote(_latin2'ab')), coercibility(quote(_latin2'ab')); ...@@ -155,16 +165,27 @@ select collation(quote(_latin2'ab')), coercibility(quote(_latin2'ab'));
select collation(soundex(_latin2'ab')), coercibility(soundex(_latin2'ab')); select collation(soundex(_latin2'ab')), coercibility(soundex(_latin2'ab'));
select collation(substring(_latin2'ab',1)), coercibility(substring(_latin2'ab',1)); select collation(substring(_latin2'ab',1)), coercibility(substring(_latin2'ab',1));
select collation(insert(_latin2'abcd',2,3,_latin2'ef')), coercibility(insert(_latin2'abcd',2,3,_latin2'ef')); select collation(insert(_latin2'abcd',2,3,_latin2'ef')), coercibility(insert(_latin2'abcd',2,3,_latin2'ef'));
select collation(replace(_latin2'abcd',_latin2'b',_latin2'B')), coercibility(replace(_latin2'abcd',_latin2'b',_latin2'B'));
create table t1 create table t1
select select
bin(130),
oct(130),
conv(130,16,10),
hex(130),
char(130),
format(130,10),
left(_latin2'a',1), left(_latin2'a',1),
right(_latin2'a',1), right(_latin2'a',1),
lcase(_latin2'a'), lcase(_latin2'a'),
ucase(_latin2'a'), ucase(_latin2'a'),
substring(_latin2'a',1,1), substring(_latin2'a',1,1),
concat(_latin2'a',_latin2'b'), concat(_latin2'a',_latin2'b'),
lpad(_latin2'a',4,_latin2'b'),
rpad(_latin2'a',4,_latin2'b'),
concat_ws(_latin2'a',_latin2'b'), concat_ws(_latin2'a',_latin2'b'),
make_set(255,_latin2'a',_latin2'b',_latin2'c'),
export_set(255,_latin2'y',_latin2'n',_latin2' '),
trim(_latin2' a '), trim(_latin2' a '),
ltrim(_latin2' a '), ltrim(_latin2' a '),
rtrim(_latin2' a '), rtrim(_latin2' a '),
...@@ -176,8 +197,8 @@ select ...@@ -176,8 +197,8 @@ select
quote(_latin2'ab'), quote(_latin2'ab'),
soundex(_latin2'ab'), soundex(_latin2'ab'),
substring(_latin2'ab',1), substring(_latin2'ab',1),
insert(_latin2'abcd',2,3,_latin2'ef') insert(_latin2'abcd',2,3,_latin2'ef'),
replace(_latin2'abcd',_latin2'b',_latin2'B')
; ;
show create table t1; show create table t1;
drop table t1; drop table t1;
#
# Testing of PRELOAD
#
--disable_warnings
drop table if exists t1, t2;
--enable_warnings
create table t1 (
a int not null auto_increment,
b char(16) not null,
primary key (a),
key (b)
);
create table t2(
a int not null auto_increment,
b char(16) not null,
primary key (a),
key (b)
);
insert into t1(b) values
('test0'),
('test1'),
('test2'),
('test3'),
('test4'),
('test5'),
('test6'),
('test7');
insert into t2(b) select b from t1;
insert into t1(b) select b from t2;
insert into t2(b) select b from t1;
insert into t1(b) select b from t2;
insert into t2(b) select b from t1;
insert into t1(b) select b from t2;
insert into t2(b) select b from t1;
insert into t1(b) select b from t2;
insert into t2(b) select b from t1;
insert into t1(b) select b from t2;
insert into t2(b) select b from t1;
insert into t1(b) select b from t2;
insert into t2(b) select b from t1;
insert into t1(b) select b from t2;
insert into t2(b) select b from t1;
insert into t1(b) select b from t2;
insert into t2(b) select b from t1;
insert into t1(b) select b from t2;
select count(*) from t1;
select count(*) from t2;
flush tables; flush status;
show status like "key_read%";
select count(*) from t1 where b = 'test1';
show status like "key_read%";
select count(*) from t1 where b = 'test1';
show status like "key_read%";
flush tables; flush status;
select @@preload_buffer_size;
load index into cache t1 keys;
show status like "key_read%";
select count(*) from t1 where b = 'test1';
show status like "key_read%";
flush tables; flush status;
show status like "key_read%";
set session preload_buffer_size=256*1024;
select @@preload_buffer_size;
load index into cache t1 keys ignore leaves;
show status like "key_read%";
select count(*) from t1 where b = 'test1';
show status like "key_read%";
flush tables; flush status;
show status like "key_read%";
set session preload_buffer_size=1*1024;
select @@preload_buffer_size;
load index into cache t1 keys, t2 keys (primary,b) ignore leaves;
show status like "key_read%";
select count(*) from t1 where b = 'test1';
select count(*) from t2 where b = 'test1';
show status like "key_read%";
flush tables; flush status;
show status like "key_read%";
load index into cache t3 keys, t2 keys (primary,b) ;
show status like "key_read%";
flush tables; flush status;
show status like "key_read%";
load index into cache t3 keys (b), t2 keys (c) ;
show status like "key_read%";
drop table t1, t2;
...@@ -826,7 +826,7 @@ restart: ...@@ -826,7 +826,7 @@ restart:
(uint) hash_link->file,(ulong) hash_link->diskpos)); (uint) hash_link->file,(ulong) hash_link->diskpos));
} }
} }
KEYCACHE_DBUG_ASSERT(n <= my_hash_links_used); KEYCACHE_DBUG_ASSERT(cnt <= my_hash_links_used);
#endif #endif
} }
if (! hash_link) if (! hash_link)
...@@ -1063,6 +1063,9 @@ restart: ...@@ -1063,6 +1063,9 @@ restart:
KEYCACHE_DBUG_ASSERT(page_status != -1); KEYCACHE_DBUG_ASSERT(page_status != -1);
*page_st=page_status; *page_st=page_status;
KEYCACHE_DBUG_PRINT("find_key_block",
("file %u, filepos %lu, page_status %lu",
(uint) file,(ulong) filepos,(uint) page_status));
#if !defined(DBUG_OFF) && defined(EXTRA_DEBUG) #if !defined(DBUG_OFF) && defined(EXTRA_DEBUG)
DBUG_EXECUTE("check_keycache2",test_key_cache("end of find_key_block",0);); DBUG_EXECUTE("check_keycache2",test_key_cache("end of find_key_block",0););
...@@ -1181,7 +1184,7 @@ byte *key_cache_read(File file, my_off_t filepos, byte *buff, uint length, ...@@ -1181,7 +1184,7 @@ byte *key_cache_read(File file, my_off_t filepos, byte *buff, uint length,
keycache_pthread_mutex_lock(&THR_LOCK_keycache); keycache_pthread_mutex_lock(&THR_LOCK_keycache);
my_cache_r_requests++; my_cache_r_requests++;
block=find_key_block(file,filepos,0,&page_st); block=find_key_block(file,filepos,0,&page_st);
if (page_st != PAGE_READ) if (block->status != BLOCK_ERROR && page_st != PAGE_READ)
{ {
/* The requested page is to be read into the block buffer */ /* The requested page is to be read into the block buffer */
read_block(block,key_cache_block_size,read_length+offset, read_block(block,key_cache_block_size,read_length+offset,
...@@ -1255,6 +1258,86 @@ byte *key_cache_read(File file, my_off_t filepos, byte *buff, uint length, ...@@ -1255,6 +1258,86 @@ byte *key_cache_read(File file, my_off_t filepos, byte *buff, uint length,
} }
/*
Insert a block of file data from a buffer into key cache
SYNOPSIS
key_cache_insert()
file file descriptor
filepos file offset of the data from the buffer
buff buffer with data to insert into key cache
length length of the data in the buffer
RETURN VALUE
0 if a success, 1 -otherwise.
*/
int key_cache_insert(File file, my_off_t filepos, byte *buff, uint length)
{
DBUG_ENTER("key_cache_insert");
DBUG_PRINT("enter", ("file %u, filepos %lu, length %u",
(uint) file,(ulong) filepos, length));
if (my_disk_blocks > 0)
{
/* Key cache is used */
reg1 BLOCK_LINK *block;
uint offset= (uint) (filepos & (key_cache_block_size-1));
uint read_length;
int page_st;
/* Read data into key cache from buff in key_cache_block_size increments */
filepos-= offset;
do
{
read_length= length > key_cache_block_size ?
key_cache_block_size : length;
KEYCACHE_DBUG_ASSERT(read_length > 0);
keycache_pthread_mutex_lock(&THR_LOCK_keycache);
my_cache_r_requests++;
block=find_key_block(file, filepos, 0, &page_st);
if (block->status != BLOCK_ERROR && page_st != PAGE_READ)
{
/* The requested page is to be read into the block buffer */
#if !defined(SERIALIZED_READ_FROM_CACHE)
keycache_pthread_mutex_unlock(&THR_LOCK_keycache);
#endif
/* Copy data from buff */
if (!(read_length & 511))
bmove512(block->buffer+offset, buff, read_length);
else
memcpy(block->buffer+offset, buff, (size_t) read_length);
#if !defined(SERIALIZED_READ_FROM_CACHE)
keycache_pthread_mutex_lock(&THR_LOCK_keycache);
#endif
block->status= BLOCK_READ;
block->length= read_length+offset;
}
remove_reader(block);
/*
Link the block into the LRU chain
if it's the last submitted request for the block
*/
unreg_request(block,1);
keycache_pthread_mutex_unlock(&THR_LOCK_keycache);
if (block->status & BLOCK_ERROR)
DBUG_RETURN(1);
buff+=read_length;
filepos+=read_length;
offset=0;
} while ((length-= read_length));
}
DBUG_RETURN(0);
}
/* /*
Write a buffer into disk; Write a buffer into disk;
filepos must be a multiple of 'block_length', but it doesn't filepos must be a multiple of 'block_length', but it doesn't
...@@ -1303,7 +1386,7 @@ int key_cache_write(File file, my_off_t filepos, byte *buff, uint length, ...@@ -1303,7 +1386,7 @@ int key_cache_write(File file, my_off_t filepos, byte *buff, uint length,
keycache_pthread_mutex_lock(&THR_LOCK_keycache); keycache_pthread_mutex_lock(&THR_LOCK_keycache);
my_cache_w_requests++; my_cache_w_requests++;
block=find_key_block(file, filepos, 1, &page_st); block=find_key_block(file, filepos, 1, &page_st);
if (page_st != PAGE_READ && if (block->status != BLOCK_ERROR && page_st != PAGE_READ &&
(offset || read_length < key_cache_block_size)) (offset || read_length < key_cache_block_size))
read_block(block, read_block(block,
offset + read_length >= key_cache_block_size? offset + read_length >= key_cache_block_size?
......
...@@ -4,7 +4,7 @@ ALTER TABLE host type=MyISAM; ...@@ -4,7 +4,7 @@ ALTER TABLE host type=MyISAM;
ALTER TABLE func type=MyISAM; ALTER TABLE func type=MyISAM;
ALTER TABLE columns_priv type=MyISAM; ALTER TABLE columns_priv type=MyISAM;
ALTER TABLE tables_priv type=MyISAM; ALTER TABLE tables_priv type=MyISAM;
ALTER TABLE user change password password char(45) not null; ALTER TABLE user change Password Password char(45) not null;
ALTER TABLE user add File_priv enum('N','Y') NOT NULL; ALTER TABLE user add File_priv enum('N','Y') NOT NULL;
CREATE TABLE IF NOT EXISTS func ( CREATE TABLE IF NOT EXISTS func (
name char(64) DEFAULT '' NOT NULL, name char(64) DEFAULT '' NOT NULL,
......
# Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
## Process this file with automake to create Makefile.in
EXTRA_DIST = client.c pack.c
# Don't update the files from bitkeeper
%::SCCS/s.%
...@@ -688,6 +688,72 @@ int ha_myisam::repair(THD *thd, MI_CHECK &param, bool optimize) ...@@ -688,6 +688,72 @@ int ha_myisam::repair(THD *thd, MI_CHECK &param, bool optimize)
} }
/*
Preload pages of the index file for a table into the key cache.
*/
int ha_myisam::preload_keys(THD* thd, HA_CHECK_OPT *check_opt)
{
int error;
const char *errmsg;
ulonglong map= ~(ulonglong) 0;
TABLE_LIST *table_list= table->pos_in_table_list;
my_bool ignore_leaves= table_list->ignore_leaves;
DBUG_ENTER("ha_myisam::preload_keys");
/* Check validity of the index references */
if (table_list->use_index)
{
key_map kmap= get_key_map_from_key_list(table, table_list->use_index);
if (kmap == ~(key_map) 0)
{
errmsg= thd->net.last_error;
error= HA_ADMIN_FAILED;
goto err;
}
if (kmap)
map= kmap;
}
mi_extra(file, HA_EXTRA_PRELOAD_BUFFER_SIZE,
(void *) &thd->variables.preload_buff_size);
if ((error= mi_preload(file, map, ignore_leaves)))
{
switch (error) {
case HA_ERR_NON_UNIQUE_BLOCK_SIZE:
errmsg= "Indexes use different block sizes";
break;
case HA_ERR_OUT_OF_MEM:
errmsg= "Failed to allocate buffer";
break;
default:
char buf[ERRMSGSIZE+20];
my_snprintf(buf, ERRMSGSIZE,
"Failed to read from index file (errno: %d)", my_errno);
errmsg= buf;
}
error= HA_ADMIN_FAILED;
goto err;
}
DBUG_RETURN(HA_ADMIN_OK);
err:
{
MI_CHECK param;
myisamchk_init(&param);
param.thd= thd;
param.op_name= (char*)"preload_keys";
param.db_name= table->table_cache_key;
param.table_name= table->table_name;
param.testflag= 0;
mi_check_print_error(&param, errmsg);
DBUG_RETURN(error);
}
}
/* /*
Deactive all not unique index that can be recreated fast Deactive all not unique index that can be recreated fast
......
...@@ -127,6 +127,7 @@ class ha_myisam: public handler ...@@ -127,6 +127,7 @@ class ha_myisam: public handler
int optimize(THD* thd, HA_CHECK_OPT* check_opt); int optimize(THD* thd, HA_CHECK_OPT* check_opt);
int restore(THD* thd, HA_CHECK_OPT* check_opt); int restore(THD* thd, HA_CHECK_OPT* check_opt);
int backup(THD* thd, HA_CHECK_OPT* check_opt); int backup(THD* thd, HA_CHECK_OPT* check_opt);
int preload_keys(THD* thd, HA_CHECK_OPT* check_opt);
#ifdef HAVE_REPLICATION #ifdef HAVE_REPLICATION
int dump(THD* thd, int fd); int dump(THD* thd, int fd);
int net_read_dump(NET* net); int net_read_dump(NET* net);
......
...@@ -620,6 +620,11 @@ int handler::analyze(THD* thd, HA_CHECK_OPT* check_opt) ...@@ -620,6 +620,11 @@ int handler::analyze(THD* thd, HA_CHECK_OPT* check_opt)
return HA_ADMIN_NOT_IMPLEMENTED; return HA_ADMIN_NOT_IMPLEMENTED;
} }
int handler::preload_keys(THD* thd, HA_CHECK_OPT* check_opt)
{
return HA_ADMIN_NOT_IMPLEMENTED;
}
/* /*
Read first row (only) from a table Read first row (only) from a table
This is never called for InnoDB or BDB tables, as these table types This is never called for InnoDB or BDB tables, as these table types
......
...@@ -305,6 +305,7 @@ public: ...@@ -305,6 +305,7 @@ public:
virtual int optimize(THD* thd,HA_CHECK_OPT* check_opt); virtual int optimize(THD* thd,HA_CHECK_OPT* check_opt);
virtual int analyze(THD* thd, HA_CHECK_OPT* check_opt); virtual int analyze(THD* thd, HA_CHECK_OPT* check_opt);
virtual int backup(THD* thd, HA_CHECK_OPT* check_opt); virtual int backup(THD* thd, HA_CHECK_OPT* check_opt);
virtual int preload_keys(THD* thd, HA_CHECK_OPT* check_opt);
/* /*
restore assumes .frm file must exist, and that generate_table() has been restore assumes .frm file must exist, and that generate_table() has been
called; It will just copy the data file and run repair. called; It will just copy the data file and run repair.
......
...@@ -39,7 +39,7 @@ Item::Item(): ...@@ -39,7 +39,7 @@ Item::Item():
{ {
marker= 0; marker= 0;
maybe_null=null_value=with_sum_func=unsigned_flag=0; maybe_null=null_value=with_sum_func=unsigned_flag=0;
coercibility=COER_IMPLICIT; coercibility=COER_COERCIBLE;
name= 0; name= 0;
decimals= 0; max_length= 0; decimals= 0; max_length= 0;
THD *thd= current_thd; THD *thd= current_thd;
......
...@@ -813,6 +813,7 @@ null: ...@@ -813,6 +813,7 @@ null:
void Item_func_replace::fix_length_and_dec() void Item_func_replace::fix_length_and_dec()
{ {
uint i;
max_length=args[0]->max_length; max_length=args[0]->max_length;
int diff=(int) (args[2]->max_length - args[1]->max_length); int diff=(int) (args[2]->max_length - args[1]->max_length);
if (diff > 0 && args[1]->max_length) if (diff > 0 && args[1]->max_length)
...@@ -825,6 +826,20 @@ void Item_func_replace::fix_length_and_dec() ...@@ -825,6 +826,20 @@ void Item_func_replace::fix_length_and_dec()
max_length=MAX_BLOB_WIDTH; max_length=MAX_BLOB_WIDTH;
maybe_null=1; maybe_null=1;
} }
set_charset(args[0]->charset(), args[0]->coercibility);
for (i=1; i<3; i++)
{
if (set_charset(charset(), coercibility,
args[i]->charset(), args[i]->coercibility))
{
my_error(ER_CANT_AGGREGATE_COLLATIONS,MYF(0),
charset()->name,coercion_name(coercibility),
args[i]->charset()->name,coercion_name(args[i]->coercibility),
func_name());
break;
}
}
} }
...@@ -1765,8 +1780,20 @@ void Item_func_make_set::split_sum_func(Item **ref_pointer_array, ...@@ -1765,8 +1780,20 @@ void Item_func_make_set::split_sum_func(Item **ref_pointer_array,
void Item_func_make_set::fix_length_and_dec() void Item_func_make_set::fix_length_and_dec()
{ {
max_length=arg_count-1; max_length=arg_count-1;
for (uint i=1 ; i < arg_count ; i++) set_charset(args[0]->charset(), args[0]->coercibility);
for (uint i=0 ; i < arg_count ; i++)
{
max_length+=args[i]->max_length; max_length+=args[i]->max_length;
if (set_charset(charset(), coercibility,
args[i]->charset(), args[i]->coercibility))
{
my_error(ER_CANT_AGGREGATE_COLLATIONS,MYF(0),
charset()->name,coercion_name(coercibility),
args[i]->charset()->name,coercion_name(args[i]->coercibility),
func_name());
break;
}
}
used_tables_cache|=item->used_tables(); used_tables_cache|=item->used_tables();
const_item_cache&=item->const_item(); const_item_cache&=item->const_item();
with_sum_func= with_sum_func || item->with_sum_func; with_sum_func= with_sum_func || item->with_sum_func;
...@@ -1949,6 +1976,15 @@ err: ...@@ -1949,6 +1976,15 @@ err:
void Item_func_rpad::fix_length_and_dec() void Item_func_rpad::fix_length_and_dec()
{ {
if (set_charset(args[0]->charset(), args[0]->coercibility,
args[2]->charset(), args[2]->coercibility))
{
my_error(ER_CANT_AGGREGATE_COLLATIONS,MYF(0),
args[0]->charset()->name,coercion_name(args[0]->coercibility),
args[2]->charset()->name,coercion_name(args[2]->coercibility),
func_name());
}
if (args[1]->const_item()) if (args[1]->const_item())
{ {
uint32 length= (uint32) args[1]->val_int(); uint32 length= (uint32) args[1]->val_int();
...@@ -2009,6 +2045,15 @@ String *Item_func_rpad::val_str(String *str) ...@@ -2009,6 +2045,15 @@ String *Item_func_rpad::val_str(String *str)
void Item_func_lpad::fix_length_and_dec() void Item_func_lpad::fix_length_and_dec()
{ {
if (set_charset(args[0]->charset(), args[0]->coercibility,
args[2]->charset(), args[2]->coercibility))
{
my_error(ER_CANT_AGGREGATE_COLLATIONS,MYF(0),
args[0]->charset()->name,coercion_name(args[0]->coercibility),
args[2]->charset()->name,coercion_name(args[2]->coercibility),
func_name());
}
if (args[1]->const_item()) if (args[1]->const_item())
{ {
uint32 length= (uint32) args[1]->val_int(); uint32 length= (uint32) args[1]->val_int();
...@@ -2418,9 +2463,24 @@ String* Item_func_export_set::val_str(String* str) ...@@ -2418,9 +2463,24 @@ String* Item_func_export_set::val_str(String* str)
void Item_func_export_set::fix_length_and_dec() void Item_func_export_set::fix_length_and_dec()
{ {
uint i;
uint length=max(args[1]->max_length,args[2]->max_length); uint length=max(args[1]->max_length,args[2]->max_length);
uint sep_length=(arg_count > 3 ? args[3]->max_length : 1); uint sep_length=(arg_count > 3 ? args[3]->max_length : 1);
max_length=length*64+sep_length*63; max_length=length*64+sep_length*63;
set_charset(args[1]->charset(), args[1]->coercibility);
for (i=2 ; i < 4 && i < arg_count ; i++)
{
if (set_charset(charset(), coercibility,
args[i]->charset(), args[i]->coercibility))
{
my_error(ER_CANT_AGGREGATE_COLLATIONS,MYF(0),
charset()->name,coercion_name(coercibility),
args[i]->charset()->name,coercion_name(args[i]->coercibility),
func_name());
break;
}
}
} }
String* Item_func_inet_ntoa::val_str(String* str) String* Item_func_inet_ntoa::val_str(String* str)
...@@ -2557,7 +2617,7 @@ null: ...@@ -2557,7 +2617,7 @@ null:
} }
#ifdef HAVE_COMPRESS #ifdef HAVE_COMPRESS
#include "../zlib/zlib.h" #include "zlib.h"
String *Item_func_compress::val_str(String *str) String *Item_func_compress::val_str(String *str)
{ {
......
...@@ -433,6 +433,7 @@ public: ...@@ -433,6 +433,7 @@ public:
String *val_str(String *); String *val_str(String *);
void fix_length_and_dec() void fix_length_and_dec()
{ {
set_charset(default_charset());
max_length=args[0]->max_length+(args[0]->max_length-args[0]->decimals)/3; max_length=args[0]->max_length+(args[0]->max_length-args[0]->decimals)/3;
} }
const char *func_name() const { return "format"; } const char *func_name() const { return "format"; }
...@@ -444,7 +445,11 @@ class Item_func_char :public Item_str_func ...@@ -444,7 +445,11 @@ class Item_func_char :public Item_str_func
public: public:
Item_func_char(List<Item> &list) :Item_str_func(list) {} Item_func_char(List<Item> &list) :Item_str_func(list) {}
String *val_str(String *); String *val_str(String *);
void fix_length_and_dec() { maybe_null=0; max_length=arg_count; } void fix_length_and_dec()
{
set_charset(default_charset());
maybe_null=0; max_length=arg_count;
}
const char *func_name() const { return "char"; } const char *func_name() const { return "char"; }
}; };
...@@ -490,7 +495,11 @@ public: ...@@ -490,7 +495,11 @@ public:
Item_func_conv(Item *a,Item *b,Item *c) :Item_str_func(a,b,c) {} Item_func_conv(Item *a,Item *b,Item *c) :Item_str_func(a,b,c) {}
const char *func_name() const { return "conv"; } const char *func_name() const { return "conv"; }
String *val_str(String *); String *val_str(String *);
void fix_length_and_dec() { decimals=0; max_length=64; } void fix_length_and_dec()
{
set_charset(default_charset());
decimals=0; max_length=64;
}
}; };
...@@ -501,7 +510,11 @@ public: ...@@ -501,7 +510,11 @@ public:
Item_func_hex(Item *a) :Item_str_func(a) {} Item_func_hex(Item *a) :Item_str_func(a) {}
const char *func_name() const { return "hex"; } const char *func_name() const { return "hex"; }
String *val_str(String *); String *val_str(String *);
void fix_length_and_dec() { decimals=0; max_length=args[0]->max_length*2; } void fix_length_and_dec()
{
set_charset(default_charset());
decimals=0; max_length=args[0]->max_length*2;
}
}; };
......
...@@ -221,6 +221,7 @@ static SYMBOL symbols[] = { ...@@ -221,6 +221,7 @@ static SYMBOL symbols[] = {
{ "KILL", SYM(KILL_SYM),0,0}, { "KILL", SYM(KILL_SYM),0,0},
{ "LAST", SYM(LAST_SYM),0,0}, { "LAST", SYM(LAST_SYM),0,0},
{ "LEADING", SYM(LEADING),0,0}, { "LEADING", SYM(LEADING),0,0},
{ "LEAVES", SYM(LEAVES),0,0},
{ "LEFT", SYM(LEFT),0,0}, { "LEFT", SYM(LEFT),0,0},
{ "LEVEL", SYM(LEVEL_SYM),0,0}, { "LEVEL", SYM(LEVEL_SYM),0,0},
{ "LIKE", SYM(LIKE),0,0}, { "LIKE", SYM(LIKE),0,0},
......
...@@ -250,6 +250,7 @@ void debug_sync_point(const char* lock_name, uint lock_timeout); ...@@ -250,6 +250,7 @@ void debug_sync_point(const char* lock_name, uint lock_timeout);
/* Options to add_table_to_list() */ /* Options to add_table_to_list() */
#define TL_OPTION_UPDATING 1 #define TL_OPTION_UPDATING 1
#define TL_OPTION_FORCE_INDEX 2 #define TL_OPTION_FORCE_INDEX 2
#define TL_OPTION_IGNORE_LEAVES 4
/* Some portable defines */ /* Some portable defines */
...@@ -402,6 +403,8 @@ int mysql_analyze_table(THD* thd, TABLE_LIST* table_list, ...@@ -402,6 +403,8 @@ int mysql_analyze_table(THD* thd, TABLE_LIST* table_list,
HA_CHECK_OPT* check_opt); HA_CHECK_OPT* check_opt);
int mysql_optimize_table(THD* thd, TABLE_LIST* table_list, int mysql_optimize_table(THD* thd, TABLE_LIST* table_list,
HA_CHECK_OPT* check_opt); HA_CHECK_OPT* check_opt);
int mysql_preload_keys(THD* thd, TABLE_LIST* table_list);
bool check_simple_select(); bool check_simple_select();
SORT_FIELD * make_unireg_sortorder(ORDER *order, uint *length); SORT_FIELD * make_unireg_sortorder(ORDER *order, uint *length);
...@@ -593,6 +596,8 @@ enum find_item_error_report_type {REPORT_ALL_ERRORS, REPORT_EXCEPT_NOT_FOUND, ...@@ -593,6 +596,8 @@ enum find_item_error_report_type {REPORT_ALL_ERRORS, REPORT_EXCEPT_NOT_FOUND,
extern const Item **not_found_item; extern const Item **not_found_item;
Item ** find_item_in_list(Item *item, List<Item> &items, uint *counter, Item ** find_item_in_list(Item *item, List<Item> &items, uint *counter,
find_item_error_report_type report_error); find_item_error_report_type report_error);
key_map get_key_map_from_key_list(TABLE *table,
List<String> *index_list);
bool insert_fields(THD *thd,TABLE_LIST *tables, bool insert_fields(THD *thd,TABLE_LIST *tables,
const char *db_name, const char *table_name, const char *db_name, const char *table_name,
List_iterator<Item> *it); List_iterator<Item> *it);
......
...@@ -3426,6 +3426,7 @@ enum options ...@@ -3426,6 +3426,7 @@ enum options
OPT_NET_BUFFER_LENGTH, OPT_NET_RETRY_COUNT, OPT_NET_BUFFER_LENGTH, OPT_NET_RETRY_COUNT,
OPT_NET_READ_TIMEOUT, OPT_NET_WRITE_TIMEOUT, OPT_NET_READ_TIMEOUT, OPT_NET_WRITE_TIMEOUT,
OPT_OPEN_FILES_LIMIT, OPT_OPEN_FILES_LIMIT,
OPT_PRELOAD_BUFFER_SIZE,
OPT_QUERY_CACHE_LIMIT, OPT_QUERY_CACHE_MIN_RES_UNIT, OPT_QUERY_CACHE_SIZE, OPT_QUERY_CACHE_LIMIT, OPT_QUERY_CACHE_MIN_RES_UNIT, OPT_QUERY_CACHE_SIZE,
OPT_QUERY_CACHE_TYPE, OPT_RECORD_BUFFER, OPT_QUERY_CACHE_TYPE, OPT_RECORD_BUFFER,
OPT_RECORD_RND_BUFFER, OPT_RELAY_LOG_SPACE_LIMIT, OPT_RELAY_LOG_PURGE, OPT_RECORD_RND_BUFFER, OPT_RELAY_LOG_SPACE_LIMIT, OPT_RELAY_LOG_PURGE,
...@@ -4234,6 +4235,11 @@ replicating a LOAD DATA INFILE command.", ...@@ -4234,6 +4235,11 @@ replicating a LOAD DATA INFILE command.",
"If this is not 0, then mysqld will use this value to reserve file descriptors to use with setrlimit(). If this value is 0 then mysqld will reserve max_connections*5 or max_connections + table_cache*2 (whichever is larger) number of files.", "If this is not 0, then mysqld will use this value to reserve file descriptors to use with setrlimit(). If this value is 0 then mysqld will reserve max_connections*5 or max_connections + table_cache*2 (whichever is larger) number of files.",
(gptr*) &open_files_limit, (gptr*) &open_files_limit, 0, GET_ULONG, (gptr*) &open_files_limit, (gptr*) &open_files_limit, 0, GET_ULONG,
REQUIRED_ARG, 0, 0, 65535, 0, 1, 0}, REQUIRED_ARG, 0, 0, 65535, 0, 1, 0},
{"preload_buffer_size", OPT_PRELOAD_BUFFER_SIZE,
"The size of the buffer that is allocated when preloading indexes",
(gptr*) &global_system_variables.preload_buff_size,
(gptr*) &max_system_variables.preload_buff_size, 0, GET_ULONG,
REQUIRED_ARG, 32*1024L, 1024, 1024*1024*1024L, 0, 1, 0},
#ifdef HAVE_QUERY_CACHE #ifdef HAVE_QUERY_CACHE
{"query_cache_limit", OPT_QUERY_CACHE_LIMIT, {"query_cache_limit", OPT_QUERY_CACHE_LIMIT,
"Don't cache results that are bigger than this.", "Don't cache results that are bigger than this.",
......
...@@ -210,6 +210,8 @@ sys_var_thd_ulong sys_net_retry_count("net_retry_count", ...@@ -210,6 +210,8 @@ sys_var_thd_ulong sys_net_retry_count("net_retry_count",
&SV::net_retry_count, &SV::net_retry_count,
fix_net_retry_count); fix_net_retry_count);
sys_var_thd_bool sys_new_mode("new", &SV::new_mode); sys_var_thd_bool sys_new_mode("new", &SV::new_mode);
sys_var_thd_ulong sys_preload_buff_size("preload_buffer_size",
&SV::preload_buff_size);
sys_var_thd_ulong sys_read_buff_size("read_buffer_size", sys_var_thd_ulong sys_read_buff_size("read_buffer_size",
&SV::read_buff_size); &SV::read_buff_size);
sys_var_bool_ptr sys_readonly("read_only", &opt_readonly); sys_var_bool_ptr sys_readonly("read_only", &opt_readonly);
...@@ -423,6 +425,7 @@ sys_var *sys_variables[]= ...@@ -423,6 +425,7 @@ sys_var *sys_variables[]=
&sys_net_wait_timeout, &sys_net_wait_timeout,
&sys_net_write_timeout, &sys_net_write_timeout,
&sys_new_mode, &sys_new_mode,
&sys_preload_buff_size,
&sys_pseudo_thread_id, &sys_pseudo_thread_id,
&sys_query_cache_size, &sys_query_cache_size,
#ifdef HAVE_QUERY_CACHE #ifdef HAVE_QUERY_CACHE
...@@ -602,6 +605,7 @@ struct show_var_st init_vars[]= { ...@@ -602,6 +605,7 @@ struct show_var_st init_vars[]= {
{"log_error", (char*) log_error_file, SHOW_CHAR}, {"log_error", (char*) log_error_file, SHOW_CHAR},
{"port", (char*) &mysqld_port, SHOW_INT}, {"port", (char*) &mysqld_port, SHOW_INT},
{"protocol_version", (char*) &protocol_version, SHOW_INT}, {"protocol_version", (char*) &protocol_version, SHOW_INT},
{sys_preload_buff_size.name, (char*) &sys_preload_buff_size, SHOW_SYS},
{sys_pseudo_thread_id.name, (char*) &sys_pseudo_thread_id, SHOW_SYS}, {sys_pseudo_thread_id.name, (char*) &sys_pseudo_thread_id, SHOW_SYS},
{sys_read_buff_size.name, (char*) &sys_read_buff_size, SHOW_SYS}, {sys_read_buff_size.name, (char*) &sys_read_buff_size, SHOW_SYS},
{sys_readonly.name, (char*) &sys_readonly, SHOW_SYS}, {sys_readonly.name, (char*) &sys_readonly, SHOW_SYS},
......
...@@ -35,8 +35,6 @@ static int open_unireg_entry(THD *thd,TABLE *entry,const char *db, ...@@ -35,8 +35,6 @@ static int open_unireg_entry(THD *thd,TABLE *entry,const char *db,
const char *name, const char *alias); const char *name, const char *alias);
static void free_cache_entry(TABLE *entry); static void free_cache_entry(TABLE *entry);
static void mysql_rm_tmp_tables(void); static void mysql_rm_tmp_tables(void);
static key_map get_key_map_from_key_list(TABLE *table,
List<String> *index_list);
extern "C" byte *table_cache_key(const byte *record,uint *length, extern "C" byte *table_cache_key(const byte *record,uint *length,
...@@ -2066,8 +2064,8 @@ bool setup_tables(TABLE_LIST *tables) ...@@ -2066,8 +2064,8 @@ bool setup_tables(TABLE_LIST *tables)
} }
static key_map get_key_map_from_key_list(TABLE *table, key_map get_key_map_from_key_list(TABLE *table,
List<String> *index_list) List<String> *index_list)
{ {
key_map map=0; key_map map=0;
List_iterator_fast<String> it(*index_list); List_iterator_fast<String> it(*index_list);
......
...@@ -366,6 +366,7 @@ struct system_variables ...@@ -366,6 +366,7 @@ struct system_variables
ulong net_retry_count; ulong net_retry_count;
ulong net_wait_timeout; ulong net_wait_timeout;
ulong net_write_timeout; ulong net_write_timeout;
ulong preload_buff_size;
ulong query_cache_type; ulong query_cache_type;
ulong read_buff_size; ulong read_buff_size;
ulong read_rnd_buff_size; ulong read_rnd_buff_size;
......
...@@ -59,7 +59,7 @@ enum enum_sql_command { ...@@ -59,7 +59,7 @@ enum enum_sql_command {
SQLCOM_CHANGE_DB, SQLCOM_CREATE_DB, SQLCOM_DROP_DB, SQLCOM_ALTER_DB, SQLCOM_CHANGE_DB, SQLCOM_CREATE_DB, SQLCOM_DROP_DB, SQLCOM_ALTER_DB,
SQLCOM_REPAIR, SQLCOM_REPLACE, SQLCOM_REPLACE_SELECT, SQLCOM_REPAIR, SQLCOM_REPLACE, SQLCOM_REPLACE_SELECT,
SQLCOM_CREATE_FUNCTION, SQLCOM_DROP_FUNCTION, SQLCOM_CREATE_FUNCTION, SQLCOM_DROP_FUNCTION,
SQLCOM_REVOKE,SQLCOM_OPTIMIZE, SQLCOM_CHECK, SQLCOM_REVOKE,SQLCOM_OPTIMIZE, SQLCOM_CHECK, SQLCOM_PRELOAD_KEYS,
SQLCOM_FLUSH, SQLCOM_KILL, SQLCOM_ANALYZE, SQLCOM_FLUSH, SQLCOM_KILL, SQLCOM_ANALYZE,
SQLCOM_ROLLBACK, SQLCOM_COMMIT, SQLCOM_SLAVE_START, SQLCOM_SLAVE_STOP, SQLCOM_ROLLBACK, SQLCOM_COMMIT, SQLCOM_SLAVE_START, SQLCOM_SLAVE_STOP,
SQLCOM_BEGIN, SQLCOM_LOAD_MASTER_TABLE, SQLCOM_CHANGE_MASTER, SQLCOM_BEGIN, SQLCOM_LOAD_MASTER_TABLE, SQLCOM_CHANGE_MASTER,
......
...@@ -1881,6 +1881,15 @@ mysql_execute_command(THD *thd) ...@@ -1881,6 +1881,15 @@ mysql_execute_command(THD *thd)
res = mysql_restore_table(thd, tables); res = mysql_restore_table(thd, tables);
break; break;
} }
case SQLCOM_PRELOAD_KEYS:
{
if (check_db_used(thd, tables) ||
check_access(thd, INDEX_ACL, tables->db, &tables->grant.privilege))
goto error;
res = mysql_preload_keys(thd, tables);
break;
}
#ifndef EMBEDDED_LIBRARY #ifndef EMBEDDED_LIBRARY
case SQLCOM_CHANGE_MASTER: case SQLCOM_CHANGE_MASTER:
...@@ -4107,6 +4116,7 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd, ...@@ -4107,6 +4116,7 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd,
ptr->lock_type= lock_type; ptr->lock_type= lock_type;
ptr->updating= test(table_options & TL_OPTION_UPDATING); ptr->updating= test(table_options & TL_OPTION_UPDATING);
ptr->force_index= test(table_options & TL_OPTION_FORCE_INDEX); ptr->force_index= test(table_options & TL_OPTION_FORCE_INDEX);
ptr->ignore_leaves= test(table_options & TL_OPTION_IGNORE_LEAVES);
ptr->derived= table->sel; ptr->derived= table->sel;
if (use_index) if (use_index)
ptr->use_index=(List<String> *) thd->memdup((gptr) use_index, ptr->use_index=(List<String> *) thd->memdup((gptr) use_index,
......
...@@ -1404,6 +1404,7 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables, ...@@ -1404,6 +1404,7 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables,
goto err; goto err;
continue; continue;
} }
table->table->pos_in_table_list= table;
if ((table->table->db_stat & HA_READ_ONLY) && open_for_modify) if ((table->table->db_stat & HA_READ_ONLY) && open_for_modify)
{ {
char buff[FN_REFLEN + MYSQL_ERRMSG_SIZE]; char buff[FN_REFLEN + MYSQL_ERRMSG_SIZE];
...@@ -1559,6 +1560,28 @@ int mysql_optimize_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt) ...@@ -1559,6 +1560,28 @@ int mysql_optimize_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt)
} }
/*
Preload specified indexes for a table into key cache
SYNOPSIS
mysql_preload_keys()
thd Thread object
tables Table list (one table only)
RETURN VALUES
0 ok
-1 error
*/
int mysql_preload_keys(THD* thd, TABLE_LIST* tables)
{
DBUG_ENTER("mysql_preload_keys");
DBUG_RETURN(mysql_admin_table(thd, tables, 0,
"preload_keys", TL_READ, 0, 0, 0,
&handler::preload_keys));
}
/* /*
Create a table identical to the specified table Create a table identical to the specified table
......
...@@ -256,6 +256,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); ...@@ -256,6 +256,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token KEY_SYM %token KEY_SYM
%token LEADING %token LEADING
%token LEAST_SYM %token LEAST_SYM
%token LEAVES
%token LEVEL_SYM %token LEVEL_SYM
%token LEX_HOSTNAME %token LEX_HOSTNAME
%token LIKE %token LIKE
...@@ -579,7 +580,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); ...@@ -579,7 +580,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
type int_type real_type order_dir opt_field_spec lock_option type int_type real_type order_dir opt_field_spec lock_option
udf_type if_exists opt_local opt_table_options table_options udf_type if_exists opt_local opt_table_options table_options
table_option opt_if_not_exists opt_no_write_to_binlog opt_var_type opt_var_ident_type table_option opt_if_not_exists opt_no_write_to_binlog opt_var_type opt_var_ident_type
delete_option opt_temporary all_or_any opt_distinct delete_option opt_temporary all_or_any opt_distinct opt_ignore_leaves
%type <ulong_num> %type <ulong_num>
ULONG_NUM raid_types merge_insert_types ULONG_NUM raid_types merge_insert_types
...@@ -608,7 +609,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); ...@@ -608,7 +609,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
key_alg opt_btree_or_rtree key_alg opt_btree_or_rtree
%type <string_list> %type <string_list>
key_usage_list key_usage_list
%type <key_part> %type <key_part>
key_part key_part
...@@ -656,10 +657,11 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); ...@@ -656,10 +657,11 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%type <NONE> %type <NONE>
query verb_clause create change select do drop insert replace insert2 query verb_clause create change select do drop insert replace insert2
insert_values update delete truncate rename insert_values update delete truncate rename
show describe load alter optimize flush show describe load alter optimize preload flush
reset purge begin commit rollback slave master_def master_defs reset purge begin commit rollback slave master_def master_defs
repair restore backup analyze check start repair restore backup analyze check start
field_list field_list_item field_spec kill column_def key_def field_list field_list_item field_spec kill column_def key_def
preload_list preload_keys
select_item_list select_item values_list no_braces select_item_list select_item values_list no_braces
opt_limit_clause delete_limit_clause fields opt_values values opt_limit_clause delete_limit_clause fields opt_values values
procedure_list procedure_list2 procedure_item procedure_list procedure_list2 procedure_item
...@@ -728,6 +730,7 @@ verb_clause: ...@@ -728,6 +730,7 @@ verb_clause:
| lock | lock
| kill | kill
| optimize | optimize
| preload
| purge | purge
| rename | rename
| repair | repair
...@@ -1835,6 +1838,55 @@ table_to_table: ...@@ -1835,6 +1838,55 @@ table_to_table:
YYABORT; YYABORT;
}; };
preload:
LOAD INDEX INTO CACHE_SYM
{
LEX *lex=Lex;
lex->sql_command=SQLCOM_PRELOAD_KEYS;
}
preload_list
{}
;
preload_list:
preload_keys
| preload_list ',' preload_keys;
preload_keys:
table_ident preload_keys_spec opt_ignore_leaves
{
LEX *lex=Lex;
SELECT_LEX *sel= &lex->select_lex;
if (!sel->add_table_to_list(lex->thd, $1, NULL, $3,
TL_READ,
sel->get_use_index(),
(List<String> *)0))
YYABORT;
}
;
preload_keys_spec:
keys_or_index { Select->select_lex()->interval_list.empty(); }
preload_key_list_or_empty
{
LEX *lex=Lex;
SELECT_LEX *sel= &lex->select_lex;
sel->use_index= sel->interval_list;
sel->use_index_ptr= &sel->use_index;
}
;
preload_key_list_or_empty:
/* empty */
| '(' key_usage_list2 ')' {}
;
opt_ignore_leaves:
/* empty */
{ $$= 0; }
| IGNORE_SYM LEAVES { $$= TL_OPTION_IGNORE_LEAVES; }
;
/* /*
Select : retrieve data from table Select : retrieve data from table
*/ */
...@@ -4279,6 +4331,7 @@ keyword: ...@@ -4279,6 +4331,7 @@ keyword:
| INSERT_METHOD {} | INSERT_METHOD {}
| RELAY_THREAD {} | RELAY_THREAD {}
| LAST_SYM {} | LAST_SYM {}
| LEAVES {}
| LEVEL_SYM {} | LEVEL_SYM {}
| LINESTRING {} | LINESTRING {}
| LOCAL_SYM {} | LOCAL_SYM {}
......
...@@ -181,6 +181,7 @@ typedef struct st_table_list ...@@ -181,6 +181,7 @@ typedef struct st_table_list
bool straight; /* optimize with prev table */ bool straight; /* optimize with prev table */
bool updating; /* for replicate-do/ignore table */ bool updating; /* for replicate-do/ignore table */
bool force_index; /* Prefer index over table scan */ bool force_index; /* Prefer index over table scan */
bool ignore_leaves; /* Preload only non-leaf nodes */
} TABLE_LIST; } TABLE_LIST;
typedef struct st_changed_table_list typedef struct st_changed_table_list
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment